Reset node animatable properties for two frames after removing the frame callback
[platform/core/uifw/dali-core.git] / dali / internal / update / common / animatable-property.h
index 7e8fbf0..ebc2c82 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) 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.
 #include <limits>
 
 // INTERNAL INCLUDES
-#include <dali/public-api/common/dali-common.h>
-#include <dali/public-api/object/property.h>
-#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/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>
 #include <dali/internal/update/common/scene-graph-buffers.h>
+#include <dali/public-api/common/dali-common.h>
+#include <dali/public-api/object/property-input.h>
+#include <dali/public-api/object/property-types.h>
+#include <dali/public-api/object/property.h>
 
 namespace Dali
 {
-
 namespace Internal
 {
-
 namespace SceneGraph
 {
-
 /**
  * Dirty flags record whether an animatable property has changed.
  * In the frame following a change, the property is reset to a base value.
@@ -52,11 +49,12 @@ 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
+static const uint32_t RESET_FLAG = 0x02; ///< Indicates that the value should be reset to the base value in the next two frames
 
-template <class T>
+template<class T>
 class AnimatableProperty;
 
 /**
@@ -65,23 +63,21 @@ class AnimatableProperty;
 class AnimatablePropertyBase : public PropertyBase
 {
 public:
-
   /**
    * Constructor, initialize the dirty flag
    */
   AnimatablePropertyBase()
   : PropertyBase(),
-    mDirtyFlags( BAKED_FLAG )
-  {}
+    mDirtyFlags(BAKED_FLAG)
+  {
+  }
 
   /**
    * Virtual destructor.
    */
-  virtual ~AnimatablePropertyBase()
-  {}
+  ~AnimatablePropertyBase() override = default;
 
 protected: // for derived classes
-
   /**
    * Flag that the property has been Set during the current frame.
    */
@@ -98,60 +94,63 @@ protected: // for derived classes
     mDirtyFlags = BAKED_FLAG;
   }
 
-public: // From PropertyBase
+public:
+
+  /**
+   * Mark the property as dirty so that it will be reset to the base value in the next two frames.
+   */
+  void MarkAsDirty()
+  {
+    mDirtyFlags = RESET_FLAG;
+  }
 
+public: // From PropertyBase
   /**
    * @copydoc Dali::Internal::SceneGraph::PropertyBase::IsClean()
    */
-  virtual bool IsClean() const
+  bool IsClean() const override
   {
-    return ( CLEAN_FLAG == mDirtyFlags );
+    return (CLEAN_FLAG == mDirtyFlags);
   }
 
   /**
    * @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
-
+protected:              // so that ResetToBaseValue can set it directly
+  uint32_t mDirtyFlags; ///< Flag whether value changed during previous 2 frames
 };
 
-
 /**
  * An boolean animatable property of a scene-graph object.
  */
-template <>
+template<>
 class AnimatableProperty<bool> : public AnimatablePropertyBase
 {
 public:
-
   /**
    * Create an animatable property.
    * @param [in] initialValue The initial value of the property.
    */
-  AnimatableProperty( bool initialValue )
-  : mValue( initialValue ),
-    mBaseValue( initialValue )
+  AnimatableProperty(bool initialValue)
+  : mValue(initialValue),
+    mBaseValue(initialValue)
   {
   }
 
   /**
    * 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,22 +158,22 @@ public:
   /**
    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
    */
-  virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
+  void ResetToBaseValue(BufferIndex updateBufferIndex) override
   {
-    if (CLEAN_FLAG != mDirtyFlags)
+    if(CLEAN_FLAG != mDirtyFlags)
     {
       mValue[updateBufferIndex] = mBaseValue;
 
-      mDirtyFlags = ( mDirtyFlags >> 1 );
+      mDirtyFlags = (mDirtyFlags >> 1);
     }
   }
 
   /**
    * @copydoc Dali::Internal::PropertyInputImpl::GetBoolean()
    */
-  virtual const bool& GetBoolean( BufferIndex bufferIndex ) const
+  const bool& GetBoolean(BufferIndex bufferIndex) const override
   {
-    return mValue[ bufferIndex ];
+    return mValue[bufferIndex];
   }
 
   /**
@@ -186,7 +185,7 @@ public:
   void Set(BufferIndex bufferIndex, bool value)
   {
     // check if the value actually changed to avoid dirtying nodes unnecessarily
-    if( mValue[bufferIndex] != value )
+    if(mValue[bufferIndex] != value)
     {
       mValue[bufferIndex] = value;
 
@@ -203,9 +202,9 @@ public:
   {
     // check if the value actually changed to avoid dirtying nodes unnecessarily
     // false + false does not change value, true + false does not either
-    if( delta && !mValue[bufferIndex] )
+    if(delta && !mValue[bufferIndex])
     {
-      mValue[bufferIndex] += delta;
+      mValue[bufferIndex] = delta;
 
       OnSet();
     }
@@ -214,7 +213,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  bool& Get(size_t bufferIndex)
+  bool& Get(BufferIndex bufferIndex)
   {
     return mValue[bufferIndex];
   }
@@ -222,7 +221,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 +231,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 +241,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];
   }
@@ -255,10 +254,13 @@ public:
   void Bake(BufferIndex bufferIndex, bool value)
   {
     // bake has to check the base value as current buffer value can be correct by constraint or something else
-    if( mBaseValue != value )
+    if(mBaseValue != value)
     {
       mBaseValue = value;
-      mValue[bufferIndex] = 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,14 +273,13 @@ public:
    */
   void BakeRelative(BufferIndex bufferIndex, bool delta)
   {
-    mValue[bufferIndex] += delta;
-    mBaseValue = mValue[bufferIndex];
+    mValue[bufferIndex] = mValue[bufferIndex] || delta;
+    mBaseValue          = mValue[bufferIndex];
 
     OnBake();
   }
 
 private:
-
   // Undefined
   AnimatableProperty(const AnimatableProperty& property);
 
@@ -286,42 +287,36 @@ private:
   AnimatableProperty& operator=(const AnimatableProperty& rhs);
 
 private:
-
-  DoubleBuffered<bool> mValue; ///< The double-buffered property value
-  bool mBaseValue;             ///< Reset to this base value at the beginning of each frame
-
+  DoubleBuffered<bool> mValue;     ///< The double-buffered property value
+  bool                 mBaseValue; ///< Reset to this base value at the beginning of each frame
 };
 
-
 /**
  * An integer animatable property of a scene-graph object.
  */
-template <>
+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 )
+  AnimatableProperty(int initialValue)
+  : mValue(initialValue),
+    mBaseValue(initialValue)
   {
   }
 
   /**
    * 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<int>();
   }
@@ -329,22 +324,22 @@ public:
   /**
    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
    */
-  virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
+  void ResetToBaseValue(BufferIndex updateBufferIndex) override
   {
-    if (CLEAN_FLAG != mDirtyFlags)
+    if(CLEAN_FLAG != mDirtyFlags)
     {
       mValue[updateBufferIndex] = mBaseValue;
 
-      mDirtyFlags = ( mDirtyFlags >> 1 );
+      mDirtyFlags = (mDirtyFlags >> 1);
     }
   }
 
   /**
    * @copydoc Dali::Internal::PropertyInputImpl::GetInteger()
    */
-  virtual const int& GetInteger( BufferIndex bufferIndex ) const
+  const int& GetInteger(BufferIndex bufferIndex) const override
   {
-    return mValue[ bufferIndex ];
+    return mValue[bufferIndex];
   }
 
   /**
@@ -375,7 +370,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  int& Get(size_t bufferIndex)
+  int& Get(BufferIndex bufferIndex)
   {
     return mValue[bufferIndex];
   }
@@ -383,7 +378,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  const int& Get(size_t bufferIndex) const
+  const int& Get(BufferIndex bufferIndex) const
   {
     return mValue[bufferIndex];
   }
@@ -393,7 +388,7 @@ public:
    * @param[in] bufferIndex The buffer to read.
    * @return The property value.
    */
-  int& operator[](size_t bufferIndex)
+  int& operator[](BufferIndex bufferIndex)
   {
     return mValue[bufferIndex];
   }
@@ -403,7 +398,7 @@ public:
    * @param[in] bufferIndex The buffer to read.
    * @return The property value.
    */
-  const int& operator[](size_t bufferIndex) const
+  const int& operator[](BufferIndex bufferIndex) const
   {
     return mValue[bufferIndex];
   }
@@ -415,8 +410,9 @@ public:
    */
   void Bake(BufferIndex bufferIndex, int value)
   {
-    mValue[bufferIndex] = value;
-    mBaseValue = mValue[bufferIndex];
+    mValue[bufferIndex]     = value;
+    mValue[1 - bufferIndex] = value;
+    mBaseValue              = mValue[bufferIndex];
 
     OnBake();
   }
@@ -429,7 +425,7 @@ public:
   void BakeRelative(BufferIndex bufferIndex, int delta)
   {
     mValue[bufferIndex] = mValue[bufferIndex] + delta;
-    mBaseValue = mValue[bufferIndex];
+    mBaseValue          = mValue[bufferIndex];
 
     OnBake();
   }
@@ -453,13 +449,12 @@ public:
    */
   void SetInitialRelative(const int& delta)
   {
-    mValue[0] = mValue[0] + delta;
-    mValue[1] = mValue[0];
+    mValue[0]  = mValue[0] + delta;
+    mValue[1]  = mValue[0];
     mBaseValue = mValue[0];
   }
 
 private:
-
   // Undefined
   AnimatableProperty(const AnimatableProperty& property);
 
@@ -467,64 +462,59 @@ private:
   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
-
+  DoubleBuffered<int> mValue;     ///< The double-buffered property value
+  int                 mBaseValue; ///< Reset to this base value at the beginning of each frame
 };
 
 /**
- * An unsigned integer animatable property of a scene-graph object.
+ * An float animatable property of a scene-graph object.
  */
-template <>
-class AnimatableProperty<unsigned int> : public AnimatablePropertyBase
+template<>
+class AnimatableProperty<float> : public AnimatablePropertyBase
 {
 public:
-
   /**
    * Create an animatable property.
    * @param [in] initialValue The initial value of the property.
    */
-  AnimatableProperty( unsigned int initialValue )
-  : mValue( initialValue ),
-    mBaseValue( initialValue )
+  AnimatableProperty(float initialValue)
+  : mValue(initialValue),
+    mBaseValue(initialValue)
   {
   }
 
   /**
    * 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<unsigned int>();
+    return Dali::PropertyTypes::Get<float>();
   }
 
   /**
    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
    */
-  virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
+  void ResetToBaseValue(BufferIndex updateBufferIndex) override
   {
-    if (CLEAN_FLAG != mDirtyFlags)
+    if(CLEAN_FLAG != mDirtyFlags)
     {
       mValue[updateBufferIndex] = mBaseValue;
 
-      mDirtyFlags = ( mDirtyFlags >> 1 );
+      mDirtyFlags = (mDirtyFlags >> 1);
     }
   }
 
   /**
-   * @copydoc Dali::Internal::PropertyInputImpl::GetUnsignedInteger()
+   * @copydoc Dali::Internal::PropertyInputImpl::GetFloat()
    */
-  virtual const unsigned int& GetUnsignedInteger( BufferIndex bufferIndex ) const
+  const float& GetFloat(BufferIndex bufferIndex) const override
   {
-    return mValue[ bufferIndex ];
+    return mValue[bufferIndex];
   }
 
   /**
@@ -533,7 +523,7 @@ public:
    * @param[in] bufferIndex The buffer to write.
    * @param[in] value The new property value.
    */
-  void Set(BufferIndex bufferIndex, unsigned int value)
+  void Set(BufferIndex bufferIndex, float value)
   {
     mValue[bufferIndex] = value;
 
@@ -545,7 +535,7 @@ public:
    * @param[in] bufferIndex The buffer to write.
    * @param[in] delta The property will change by this amount.
    */
-  void SetRelative(BufferIndex bufferIndex, unsigned int delta)
+  void SetRelative(BufferIndex bufferIndex, float delta)
   {
     mValue[bufferIndex] = mValue[bufferIndex] + delta;
 
@@ -555,7 +545,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  unsigned int& Get(size_t bufferIndex)
+  float& Get(BufferIndex bufferIndex)
   {
     return mValue[bufferIndex];
   }
@@ -563,7 +553,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  const unsigned int& Get(size_t bufferIndex) const
+  const float& Get(BufferIndex bufferIndex) const
   {
     return mValue[bufferIndex];
   }
@@ -573,7 +563,7 @@ public:
    * @param[in] bufferIndex The buffer to read.
    * @return The property value.
    */
-  unsigned int& operator[](size_t bufferIndex)
+  float& operator[](BufferIndex bufferIndex)
   {
     return mValue[bufferIndex];
   }
@@ -583,7 +573,7 @@ public:
    * @param[in] bufferIndex The buffer to read.
    * @return The property value.
    */
-  const unsigned int& operator[](size_t bufferIndex) const
+  const float& operator[](BufferIndex bufferIndex) const
   {
     return mValue[bufferIndex];
   }
@@ -593,10 +583,13 @@ public:
    * @param[in] bufferIndex The buffer to write for the property value.
    * @param[in] value The new property value.
    */
-  void Bake(BufferIndex bufferIndex, unsigned int value)
+  void Bake(BufferIndex bufferIndex, float value)
   {
-    mValue[bufferIndex] = value;
-    mBaseValue = mValue[bufferIndex];
+    // 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();
   }
@@ -606,10 +599,10 @@ public:
    * @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, unsigned int delta)
+  void BakeRelative(BufferIndex bufferIndex, float delta)
   {
     mValue[bufferIndex] = mValue[bufferIndex] + delta;
-    mBaseValue = mValue[bufferIndex];
+    mBaseValue          = mValue[bufferIndex];
 
     OnBake();
   }
@@ -619,7 +612,7 @@ public:
    * 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 unsigned int& value)
+  void SetInitial(const float& value)
   {
     mValue[0]  = value;
     mValue[1]  = mValue[0];
@@ -631,15 +624,14 @@ public:
    * 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 unsigned int& delta)
+  void SetInitialRelative(const float& delta)
   {
-    mValue[0] = mValue[0] + delta;
-    mValue[1] = mValue[0];
+    mValue[0]  = mValue[0] + delta;
+    mValue[1]  = mValue[0];
     mBaseValue = mValue[0];
   }
 
 private:
-
   // Undefined
   AnimatableProperty(const AnimatableProperty& property);
 
@@ -647,63 +639,59 @@ private:
   AnimatableProperty& operator=(const AnimatableProperty& rhs);
 
 private:
-  DoubleBuffered<unsigned int> mValue; ///< The double-buffered property value
-  unsigned int mBaseValue;             ///< Reset to this base value at the beginning of each frame
+  DoubleBuffered<float> mValue;     ///< The double-buffered property value
+  float                 mBaseValue; ///< Reset to this base value at the beginning of each frame
 };
 
-
 /**
- * An float animatable property of a scene-graph object.
+ * An Vector2 animatable property of a scene-graph object.
  */
-template <>
-class AnimatableProperty<float> : public AnimatablePropertyBase
+template<>
+class AnimatableProperty<Vector2> : public AnimatablePropertyBase
 {
 public:
-
   /**
    * Create an animatable property.
    * @param [in] initialValue The initial value of the property.
    */
-  AnimatableProperty( float initialValue )
-  : mValue( initialValue ),
-    mBaseValue( initialValue )
+  AnimatableProperty(const Vector2& initialValue)
+  : mValue(initialValue),
+    mBaseValue(initialValue)
   {
   }
 
   /**
    * 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>();
+    return Dali::PropertyTypes::Get<Vector2>();
   }
 
   /**
    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
    */
-  virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
+  void ResetToBaseValue(BufferIndex updateBufferIndex) override
   {
-    if (CLEAN_FLAG != mDirtyFlags)
+    if(CLEAN_FLAG != mDirtyFlags)
     {
       mValue[updateBufferIndex] = mBaseValue;
 
-      mDirtyFlags = ( mDirtyFlags >> 1 );
+      mDirtyFlags = (mDirtyFlags >> 1);
     }
   }
 
   /**
-   * @copydoc Dali::Internal::PropertyInputImpl::GetFloat()
+   * @copydoc Dali::PropertyInput::GetVector2()
    */
-  virtual const float& GetFloat( BufferIndex bufferIndex ) const
+  const Vector2& GetVector2(BufferIndex bufferIndex) const override
   {
-    return mValue[ bufferIndex ];
+    return mValue[bufferIndex];
   }
 
   /**
@@ -712,7 +700,7 @@ public:
    * @param[in] bufferIndex The buffer to write.
    * @param[in] value The new property value.
    */
-  void Set(BufferIndex bufferIndex, float value)
+  void Set(BufferIndex bufferIndex, const Vector2& value)
   {
     mValue[bufferIndex] = value;
 
@@ -720,192 +708,63 @@ public:
   }
 
   /**
-   * Change the property value by a relative amount.
+   * 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] delta The property will change by this amount.
+   * @param[in] value The new X value.
    */
-  void SetRelative(BufferIndex bufferIndex, float delta)
+  void SetX(BufferIndex bufferIndex, float value)
   {
-    mValue[bufferIndex] = mValue[bufferIndex] + delta;
+    mValue[bufferIndex].x = value;
 
     OnSet();
   }
 
   /**
-   * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
-   */
-  float& Get(size_t bufferIndex)
-  {
-    return mValue[bufferIndex];
-  }
-
-  /**
-   * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
-   */
-  const float& Get(size_t bufferIndex) const
-  {
-    return mValue[bufferIndex];
-  }
-
-  /**
-   * Retrieve the property value.
-   * @param[in] bufferIndex The buffer to read.
-   * @return The property value.
-   */
-  float& operator[](size_t bufferIndex)
-  {
-    return mValue[bufferIndex];
-  }
-
-  /**
-   * Retrieve the property value.
-   * @param[in] bufferIndex The buffer to read.
-   * @return The property value.
-   */
-  const float& operator[](size_t 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, float value)
-  {
-    mValue[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.
+   * 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 BakeRelative(BufferIndex bufferIndex, float delta)
+  void SetY(BufferIndex bufferIndex, float value)
   {
-    mValue[bufferIndex] = mValue[bufferIndex] + delta;
-    mBaseValue = mValue[bufferIndex];
-
-    OnBake();
-  }
+    mValue[bufferIndex].y = value;
 
-  /**
-   * 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 float& value)
-  {
-    mValue[0]  = value;
-    mValue[1]  = mValue[0];
-    mBaseValue = mValue[0];
+    OnSet();
   }
 
   /**
-   * 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.
+   * 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 SetInitialRelative(const float& 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<float> mValue; ///< The double-buffered property value
-  float mBaseValue;             ///< Reset to this base value at the beginning of each frame
-};
-
-/**
- * An Vector2 animatable property of a scene-graph object.
- */
-template <>
-class AnimatableProperty<Vector2> : public AnimatablePropertyBase
-{
-public:
-
-  /**
-   * Create an animatable property.
-   * @param [in] initialValue The initial value of the property.
-   */
-  AnimatableProperty( const Vector2& initialValue )
-  : mValue( initialValue ),
-    mBaseValue( initialValue )
-  {
-  }
-
-  /**
-   * Virtual destructor.
-   */
-  virtual ~AnimatableProperty()
-  {
-  }
-
-  /**
-   * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
-   */
-  virtual Dali::Property::Type GetType() const
-  {
-    return Dali::PropertyTypes::Get<Vector2>();
-  }
-
-  /**
-   * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
-   */
-  virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
+  void SetRelative(BufferIndex bufferIndex, const Vector2& delta)
   {
-    if (CLEAN_FLAG != mDirtyFlags)
-    {
-      mValue[updateBufferIndex] = mBaseValue;
-
-      mDirtyFlags = ( mDirtyFlags >> 1 );
-    }
-  }
+    mValue[bufferIndex] += delta;
 
-  /**
-   * @copydoc Dali::PropertyInput::GetVector2()
-   */
-  virtual const Vector2& GetVector2( BufferIndex bufferIndex ) const
-  {
-    return mValue[ bufferIndex ];
+    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.
+   * Change the X value by a relative amount.
    * @param[in] bufferIndex The buffer to write.
-   * @param[in] value The new property value.
+   * @param[in] delta The X value will change by this amount.
    */
-  void Set(BufferIndex bufferIndex, const Vector2& value)
+  void SetXRelative(BufferIndex bufferIndex, float delta)
   {
-    mValue[bufferIndex] = value;
+    mValue[bufferIndex].x += delta;
 
     OnSet();
   }
 
   /**
-   * Change the property value by a relative amount.
+   * Change the Y value by a relative amount.
    * @param[in] bufferIndex The buffer to write.
-   * @param[in] delta The property will change by this amount.
+   * @param[in] delta The Y value will change by this amount.
    */
-  void SetRelative(BufferIndex bufferIndex, const Vector2& delta)
+  void SetYRelative(BufferIndex bufferIndex, float delta)
   {
-    mValue[bufferIndex] += delta;
+    mValue[bufferIndex].y += delta;
 
     OnSet();
   }
@@ -913,7 +772,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  Vector2& Get(size_t bufferIndex)
+  Vector2& Get(BufferIndex bufferIndex)
   {
     return mValue[bufferIndex];
   }
@@ -921,7 +780,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  const Vector2& Get(size_t bufferIndex) const
+  const Vector2& Get(BufferIndex bufferIndex) const
   {
     return mValue[bufferIndex];
   }
@@ -931,7 +790,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];
   }
@@ -941,7 +800,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];
   }
@@ -953,8 +812,39 @@ public:
    */
   void Bake(BufferIndex bufferIndex, const Vector2& 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;
+    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();
   }
@@ -972,8 +862,33 @@ public:
     OnBake();
   }
 
-private:
+  /**
+   * 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
   AnimatableProperty(const AnimatableProperty& property);
 
@@ -981,20 +896,17 @@ private:
   AnimatableProperty& operator=(const AnimatableProperty& rhs);
 
 private:
-
-  DoubleBuffered<Vector2> mValue; ///< The double-buffered property value
-  Vector2 mBaseValue;             ///< Reset to this base value at the beginning of each frame
-
+  DoubleBuffered<Vector2> mValue;     ///< The double-buffered property value
+  Vector2                 mBaseValue; ///< Reset to this base value at the beginning of each frame
 };
 
 /**
  * A Vector3 animatable property of a scene-graph object.
  */
-template <>
+template<>
 class AnimatableProperty<Vector3> : public AnimatablePropertyBase
 {
 public:
-
   /**
    * Create an animatable property.
    */
@@ -1008,23 +920,21 @@ public:
    * Create an animatable property.
    * @param [in] initialValue The initial value of the property.
    */
-  AnimatableProperty( const Vector3& initialValue )
-  : mValue( initialValue ),
-    mBaseValue( initialValue )
+  AnimatableProperty(const Vector3& initialValue)
+  : mValue(initialValue),
+    mBaseValue(initialValue)
   {
   }
 
   /**
    * 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>();
   }
@@ -1032,22 +942,22 @@ public:
   /**
    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
    */
-  virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
+  void ResetToBaseValue(BufferIndex updateBufferIndex) override
   {
-    if (CLEAN_FLAG != mDirtyFlags)
+    if(CLEAN_FLAG != mDirtyFlags)
     {
       mValue[updateBufferIndex] = mBaseValue;
 
-      mDirtyFlags = ( mDirtyFlags >> 1 );
+      mDirtyFlags = (mDirtyFlags >> 1);
     }
   }
 
   /**
    * @copydoc Dali::PropertyInput::GetVector3()
    */
-  virtual const Vector3& GetVector3( BufferIndex bufferIndex ) const
+  const Vector3& GetVector3(BufferIndex bufferIndex) const override
   {
-    return mValue[ bufferIndex ];
+    return mValue[bufferIndex];
   }
 
   /**
@@ -1153,7 +1063,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  Vector3& Get(size_t bufferIndex)
+  Vector3& Get(BufferIndex bufferIndex)
   {
     return mValue[bufferIndex];
   }
@@ -1161,7 +1071,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  const Vector3& Get(size_t bufferIndex) const
+  const Vector3& Get(BufferIndex bufferIndex) const
   {
     return mValue[bufferIndex];
   }
@@ -1171,7 +1081,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];
   }
@@ -1181,7 +1091,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];
   }
@@ -1193,8 +1103,9 @@ public:
    */
   void Bake(BufferIndex bufferIndex, const Vector3& value)
   {
-    mValue[bufferIndex] = value;
-    mBaseValue = value;
+    mValue[bufferIndex]     = value;
+    mValue[1 - bufferIndex] = value;
+    mBaseValue              = value;
 
     OnBake();
   }
@@ -1206,8 +1117,9 @@ public:
    */
   void BakeX(BufferIndex bufferIndex, float value)
   {
-    mValue[bufferIndex].x = value;
-    mBaseValue.x = value;
+    mValue[bufferIndex].x     = value;
+    mValue[1 - bufferIndex].x = value;
+    mBaseValue.x              = value;
 
     OnBake();
   }
@@ -1219,8 +1131,9 @@ public:
    */
   void BakeY(BufferIndex bufferIndex, float value)
   {
-    mValue[bufferIndex].y = value;
-    mBaseValue.y = value;
+    mValue[bufferIndex].y     = value;
+    mValue[1 - bufferIndex].y = value;
+    mBaseValue.y              = value;
 
     OnBake();
   }
@@ -1232,8 +1145,9 @@ public:
    */
   void BakeZ(BufferIndex bufferIndex, float value)
   {
-    mValue[bufferIndex].z = value;
-    mBaseValue.z = value;
+    mValue[bufferIndex].z     = value;
+    mValue[1 - bufferIndex].z = value;
+    mBaseValue.z              = value;
 
     OnBake();
   }
@@ -1304,7 +1218,6 @@ public:
   }
 
 private:
-
   // Undefined
   AnimatableProperty(const AnimatableProperty& property);
 
@@ -1312,41 +1225,36 @@ private:
   AnimatableProperty& operator=(const AnimatableProperty& rhs);
 
 private:
-
-  DoubleBuffered<Vector3> mValue; ///< The double-buffered property value
-  Vector3 mBaseValue;             ///< Reset to this base value at the beginning of each frame
-
+  DoubleBuffered<Vector3> mValue;     ///< The double-buffered property value
+  Vector3                 mBaseValue; ///< Reset to this base value at the beginning of each frame
 };
 
 /**
  * A Vector4 animatable property of a scene-graph object.
  */
-template <>
+template<>
 class AnimatableProperty<Vector4> : public AnimatablePropertyBase
 {
 public:
-
   /**
    * Create an animatable property.
    * @param [in] initialValue The initial value of the property.
    */
-  AnimatableProperty( const Vector4& initialValue )
-  : mValue( initialValue ),
-    mBaseValue( initialValue )
+  AnimatableProperty(const Vector4& initialValue)
+  : mValue(initialValue),
+    mBaseValue(initialValue)
   {
   }
 
   /**
    * 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>();
   }
@@ -1354,22 +1262,22 @@ public:
   /**
    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
    */
-  virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
+  void ResetToBaseValue(BufferIndex updateBufferIndex) override
   {
-    if (CLEAN_FLAG != mDirtyFlags)
+    if(CLEAN_FLAG != mDirtyFlags)
     {
       mValue[updateBufferIndex] = mBaseValue;
 
-      mDirtyFlags = ( mDirtyFlags >> 1 );
+      mDirtyFlags = (mDirtyFlags >> 1);
     }
   }
 
   /**
    * @copydoc Dali::PropertyInput::GetVector4()
    */
-  virtual const Vector4& GetVector4( BufferIndex bufferIndex ) const
+  const Vector4& GetVector4(BufferIndex bufferIndex) const override
   {
-    return mValue[ bufferIndex ];
+    return mValue[bufferIndex];
   }
 
   /**
@@ -1500,7 +1408,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  Vector4& Get(size_t bufferIndex)
+  Vector4& Get(BufferIndex bufferIndex)
   {
     return mValue[bufferIndex];
   }
@@ -1508,7 +1416,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  const Vector4& Get(size_t bufferIndex) const
+  const Vector4& Get(BufferIndex bufferIndex) const
   {
     return mValue[bufferIndex];
   }
@@ -1518,7 +1426,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];
   }
@@ -1528,7 +1436,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];
   }
@@ -1540,8 +1448,9 @@ public:
    */
   void Bake(BufferIndex bufferIndex, const Vector4& value)
   {
-    mValue[bufferIndex] = value;
-    mBaseValue = mValue[bufferIndex];
+    mValue[bufferIndex]     = value;
+    mValue[1 - bufferIndex] = value;
+    mBaseValue              = mValue[bufferIndex];
 
     OnBake();
   }
@@ -1553,8 +1462,9 @@ public:
    */
   void BakeX(BufferIndex bufferIndex, float value)
   {
-    mValue[bufferIndex].x = value;
-    mBaseValue.x = mValue[bufferIndex].x;
+    mValue[bufferIndex].x     = value;
+    mValue[1 - bufferIndex].x = value;
+    mBaseValue.x              = mValue[bufferIndex].x;
 
     OnBake();
   }
@@ -1566,8 +1476,9 @@ public:
    */
   void BakeY(BufferIndex bufferIndex, float value)
   {
-    mValue[bufferIndex].y = value;
-    mBaseValue.y = mValue[bufferIndex].y;
+    mValue[bufferIndex].y     = value;
+    mValue[1 - bufferIndex].y = value;
+    mBaseValue.y              = mValue[bufferIndex].y;
 
     OnBake();
   }
@@ -1579,8 +1490,9 @@ public:
    */
   void BakeZ(BufferIndex bufferIndex, float value)
   {
-    mValue[bufferIndex].z = value;
-    mBaseValue.z = mValue[bufferIndex].z;
+    mValue[bufferIndex].z     = value;
+    mValue[1 - bufferIndex].z = value;
+    mBaseValue.z              = mValue[bufferIndex].z;
 
     OnBake();
   }
@@ -1592,8 +1504,9 @@ public:
    */
   void BakeW(BufferIndex bufferIndex, float value)
   {
-    mValue[bufferIndex].w = value;
-    mBaseValue.w = mValue[bufferIndex].w;
+    mValue[bufferIndex].w     = value;
+    mValue[1 - bufferIndex].w = value;
+    mBaseValue.w              = mValue[bufferIndex].w;
 
     OnBake();
   }
@@ -1606,7 +1519,7 @@ public:
   void BakeRelative(BufferIndex bufferIndex, const Vector4& delta)
   {
     mValue[bufferIndex] = mValue[bufferIndex] + delta;
-    mBaseValue = mValue[bufferIndex];
+    mBaseValue          = mValue[bufferIndex];
 
     OnBake();
   }
@@ -1619,7 +1532,7 @@ public:
   void BakeXRelative(BufferIndex bufferIndex, float delta)
   {
     mValue[bufferIndex].x = mValue[bufferIndex].x + delta;
-    mBaseValue.x = mValue[bufferIndex].x;
+    mBaseValue.x          = mValue[bufferIndex].x;
 
     OnBake();
   }
@@ -1632,7 +1545,7 @@ public:
   void BakeYRelative(BufferIndex bufferIndex, float delta)
   {
     mValue[bufferIndex].y = mValue[bufferIndex].y + delta;
-    mBaseValue.y = mValue[bufferIndex].y;
+    mBaseValue.y          = mValue[bufferIndex].y;
 
     OnBake();
   }
@@ -1645,7 +1558,7 @@ public:
   void BakeZRelative(BufferIndex bufferIndex, float delta)
   {
     mValue[bufferIndex].z = mValue[bufferIndex].z + delta;
-    mBaseValue.z = mValue[bufferIndex].z;
+    mBaseValue.z          = mValue[bufferIndex].z;
 
     OnBake();
   }
@@ -1658,7 +1571,7 @@ public:
   void BakeWRelative(BufferIndex bufferIndex, float delta)
   {
     mValue[bufferIndex].w = mValue[bufferIndex].w + delta;
-    mBaseValue.w = mValue[bufferIndex].w;
+    mBaseValue.w          = mValue[bufferIndex].w;
 
     OnBake();
   }
@@ -1676,7 +1589,6 @@ public:
   }
 
 private:
-
   // Undefined
   AnimatableProperty(const AnimatableProperty& property);
 
@@ -1684,19 +1596,16 @@ private:
   AnimatableProperty& operator=(const AnimatableProperty& rhs);
 
 private:
-
-  DoubleBuffered<Vector4> mValue; ///< The double-buffered property value
-  Vector4 mBaseValue;             ///< Reset to this base value at the beginning of each frame
-
+  DoubleBuffered<Vector4> mValue;     ///< The double-buffered property value
+  Vector4                 mBaseValue; ///< Reset to this base value at the beginning of each frame
 };
 /**
  * An Quaternion animatable property of a scene-graph object.
  */
-template <>
+template<>
 class AnimatableProperty<Quaternion> : public AnimatablePropertyBase
 {
 public:
-
   /**
    * Create an animatable property.
    */
@@ -1710,23 +1619,21 @@ public:
    * Create an animatable property.
    * @param [in] initialValue The initial value of the property.
    */
-  AnimatableProperty( const Quaternion& initialValue )
-  : mValue( initialValue ),
-    mBaseValue( initialValue )
+  AnimatableProperty(const Quaternion& initialValue)
+  : mValue(initialValue),
+    mBaseValue(initialValue)
   {
   }
 
   /**
    * 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>();
   }
@@ -1734,22 +1641,22 @@ public:
   /**
    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
    */
-  virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
+  void ResetToBaseValue(BufferIndex updateBufferIndex) override
   {
-    if (CLEAN_FLAG != mDirtyFlags)
+    if(CLEAN_FLAG != mDirtyFlags)
     {
       mValue[updateBufferIndex] = mBaseValue;
 
-      mDirtyFlags = ( mDirtyFlags >> 1 );
+      mDirtyFlags = (mDirtyFlags >> 1);
     }
   }
 
   /**
    * @copydoc Dali::PropertyInput::GetQuaternion()
    */
-  virtual const Quaternion& GetQuaternion( BufferIndex bufferIndex ) const
+  const Quaternion& GetQuaternion(BufferIndex bufferIndex) const override
   {
-    return mValue[ bufferIndex ];
+    return mValue[bufferIndex];
   }
 
   /**
@@ -1780,7 +1687,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  Quaternion& Get(size_t bufferIndex)
+  Quaternion& Get(BufferIndex bufferIndex)
   {
     return mValue[bufferIndex];
   }
@@ -1788,7 +1695,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  const Quaternion& Get(size_t bufferIndex) const
+  const Quaternion& Get(BufferIndex bufferIndex) const
   {
     return mValue[bufferIndex];
   }
@@ -1798,7 +1705,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];
   }
@@ -1808,7 +1715,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];
   }
@@ -1820,8 +1727,11 @@ public:
    */
   void Bake(BufferIndex bufferIndex, const Quaternion& 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;
+    mBaseValue              = value;
 
     OnBake();
   }
@@ -1840,7 +1750,6 @@ public:
   }
 
 private:
-
   // Undefined
   AnimatableProperty(const AnimatableProperty& property);
 
@@ -1848,41 +1757,36 @@ private:
   AnimatableProperty& operator=(const AnimatableProperty& rhs);
 
 private:
-
-  DoubleBuffered<Quaternion> mValue; ///< The double-buffered property value
-  Quaternion mBaseValue;             ///< Reset to this base value at the beginning of each frame
-
+  DoubleBuffered<Quaternion> mValue;     ///< The double-buffered property value
+  Quaternion                 mBaseValue; ///< Reset to this base value at the beginning of each frame
 };
 
 /**
  * A Matrix animatable property of a scene-graph object.
  */
-template <>
+template<>
 class AnimatableProperty<Matrix> : public AnimatablePropertyBase
 {
 public:
-
   /**
    * Create an animatable property.
    * @param [in] initialValue The initial value of the property.
    */
-  AnimatableProperty( const Matrix& initialValue )
-  : mValue( initialValue ),
-    mBaseValue( initialValue )
+  AnimatableProperty(const Matrix& initialValue)
+  : mValue(initialValue),
+    mBaseValue(initialValue)
   {
   }
 
   /**
    * 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>();
   }
@@ -1890,22 +1794,22 @@ public:
   /**
    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
    */
-  virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
+  void ResetToBaseValue(BufferIndex updateBufferIndex) override
   {
-    if (CLEAN_FLAG != mDirtyFlags)
+    if(CLEAN_FLAG != mDirtyFlags)
     {
       mValue[updateBufferIndex] = mBaseValue;
 
-      mDirtyFlags = ( mDirtyFlags >> 1 );
+      mDirtyFlags = (mDirtyFlags >> 1);
     }
   }
 
   /**
    * @copydoc Dali::Internal::PropertyInputImpl::GetMatrix()
    */
-  virtual const Matrix& GetMatrix( BufferIndex bufferIndex ) const
+  const Matrix& GetMatrix(BufferIndex bufferIndex) const override
   {
-    return mValue[ bufferIndex ];
+    return mValue[bufferIndex];
   }
 
   /**
@@ -1920,7 +1824,6 @@ public:
     OnSet();
   }
 
-
   /**
    * Change the property value by a relative amount.
    * @param[in] bufferIndex The buffer to write.
@@ -1938,7 +1841,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  Matrix& Get(size_t bufferIndex)
+  Matrix& Get(BufferIndex bufferIndex)
   {
     return mValue[bufferIndex];
   }
@@ -1946,7 +1849,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  const Matrix& Get(size_t bufferIndex) const
+  const Matrix& Get(BufferIndex bufferIndex) const
   {
     return mValue[bufferIndex];
   }
@@ -1956,7 +1859,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];
   }
@@ -1966,7 +1869,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];
   }
@@ -1978,8 +1881,11 @@ public:
    */
   void Bake(BufferIndex bufferIndex, const Matrix& value)
   {
-    mValue[bufferIndex] = value;
-    mBaseValue = mValue[bufferIndex];
+    // 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();
   }
@@ -1994,13 +1900,12 @@ public:
     Matrix temp;
     Matrix::Multiply(temp, mValue[bufferIndex], delta);
     mValue[bufferIndex] = temp;
-    mBaseValue = temp;
+    mBaseValue          = temp;
 
     OnBake();
   }
 
 private:
-
   // Undefined
   AnimatableProperty(const AnimatableProperty& property);
 
@@ -2008,41 +1913,36 @@ private:
   AnimatableProperty& operator=(const AnimatableProperty& rhs);
 
 private:
-
-  DoubleBuffered<Matrix> mValue; ///< The double-buffered property value
-  Matrix mBaseValue;             ///< Reset to this base value at the beginning of each frame
-
+  DoubleBuffered<Matrix> mValue;     ///< The double-buffered property value
+  Matrix                 mBaseValue; ///< Reset to this base value at the beginning of each frame
 };
 
 /**
  * A Matrix3 animatable property of a scene-graph object.
  */
-template <>
+template<>
 class AnimatableProperty<Matrix3> : public AnimatablePropertyBase
 {
 public:
-
   /**
    * Create an animatable property.
    * @param [in] initialValue The initial value of the property.
    */
-  AnimatableProperty( const Matrix3& initialValue )
-  : mValue( initialValue ),
-    mBaseValue( initialValue )
+  AnimatableProperty(const Matrix3& initialValue)
+  : mValue(initialValue),
+    mBaseValue(initialValue)
   {
   }
 
   /**
    * 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>();
   }
@@ -2050,22 +1950,22 @@ public:
   /**
    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
    */
-  virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
+  void ResetToBaseValue(BufferIndex updateBufferIndex) override
   {
-    if (CLEAN_FLAG != mDirtyFlags)
+    if(CLEAN_FLAG != mDirtyFlags)
     {
       mValue[updateBufferIndex] = mBaseValue;
 
-      mDirtyFlags = ( mDirtyFlags >> 1 );
+      mDirtyFlags = (mDirtyFlags >> 1);
     }
   }
 
   /**
    * @copydoc Dali::Internal::PropertyInputImpl::GetMatrix3()
    */
-  virtual const Matrix3& GetMatrix3( BufferIndex bufferIndex ) const
+  const Matrix3& GetMatrix3(BufferIndex bufferIndex) const override
   {
-    return mValue[ bufferIndex ];
+    return mValue[bufferIndex];
   }
 
   /**
@@ -2096,7 +1996,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  Matrix3& Get(size_t bufferIndex)
+  Matrix3& Get(BufferIndex bufferIndex)
   {
     return mValue[bufferIndex];
   }
@@ -2104,7 +2004,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  const Matrix3& Get(size_t bufferIndex) const
+  const Matrix3& Get(BufferIndex bufferIndex) const
   {
     return mValue[bufferIndex];
   }
@@ -2114,7 +2014,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];
   }
@@ -2124,7 +2024,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];
   }
@@ -2136,8 +2036,11 @@ public:
    */
   void Bake(BufferIndex bufferIndex, const Matrix3& value)
   {
-    mValue[bufferIndex] = value;
-    mBaseValue = mValue[bufferIndex];
+    // 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();
   }
@@ -2152,13 +2055,12 @@ public:
     Matrix3 temp;
     Matrix3::Multiply(temp, mValue[bufferIndex], delta);
     mValue[bufferIndex] = temp;
-    mBaseValue = temp;
+    mBaseValue          = temp;
 
     OnBake();
   }
 
 private:
-
   // Undefined
   AnimatableProperty(const AnimatableProperty& property);
 
@@ -2166,114 +2068,112 @@ private:
   AnimatableProperty& operator=(const AnimatableProperty& rhs);
 
 private:
-
-  DoubleBuffered<Matrix3> mValue; ///< The double-buffered property value
-  Matrix3 mBaseValue;             ///< Reset to this base value at the beginning of each frame
-
+  DoubleBuffered<Matrix3> mValue;     ///< The double-buffered property value
+  Matrix3                 mBaseValue; ///< Reset to this base value at the beginning of each frame
 };
 
 } // namespace SceneGraph
 
 // Messages for AnimatableProperty<T>
 
-template <class T>
-void BakeMessage( EventThreadServices& eventThreadServices,
-                  const SceneGraph::AnimatableProperty<T>& property,
-                  typename ParameterType< T >::PassingType newValue )
+template<class T>
+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 = eventThreadServices.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,
-                        &SceneGraph::AnimatableProperty<T>::Bake,
-                        newValue );
+  new(slot) LocalType(&property,
+                      &SceneGraph::AnimatableProperty<T>::Bake,
+                      newValue);
 }
 
-template <class T>
-void BakeRelativeMessage( EventThreadServices& eventThreadServices,
-                          const SceneGraph::AnimatableProperty<T>& property,
-                          const T& delta )
+template<class T>
+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 = eventThreadServices.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,
-                        &SceneGraph::AnimatableProperty<T>::BakeRelative,
-                         delta );
+  new(slot) LocalType(&property,
+                      &SceneGraph::AnimatableProperty<T>::BakeRelative,
+                      delta);
 }
 
-template <class T>
-void SetXComponentMessage( EventThreadServices& eventThreadServices,
-                           const SceneGraph::AnimatableProperty<T>& property,
-                           typename ParameterType< float >::PassingType newValue )
+template<class T>
+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 = eventThreadServices.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,
-                        &SceneGraph::AnimatableProperty<T>::BakeX,
-                        newValue );
+  new(slot) LocalType(&property,
+                      &SceneGraph::AnimatableProperty<T>::BakeX,
+                      newValue);
 }
 
-template <class T>
-void SetYComponentMessage( EventThreadServices& eventThreadServices,
-                           const SceneGraph::AnimatableProperty<T>& property,
-                           typename ParameterType< float >::PassingType newValue )
+template<class T>
+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 = eventThreadServices.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,
-                        &SceneGraph::AnimatableProperty<T>::BakeY,
-                        newValue );
+  new(slot) LocalType(&property,
+                      &SceneGraph::AnimatableProperty<T>::BakeY,
+                      newValue);
 }
 
-template <class T>
-void SetZComponentMessage( EventThreadServices& eventThreadServices,
-                           const SceneGraph::AnimatableProperty<T>& property,
-                           typename ParameterType< float >::PassingType newValue )
+template<class T>
+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 = eventThreadServices.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,
-                        &SceneGraph::AnimatableProperty<T>::BakeZ,
-                        newValue );
+  new(slot) LocalType(&property,
+                      &SceneGraph::AnimatableProperty<T>::BakeZ,
+                      newValue);
 }
 
-template <class T>
-void SetWComponentMessage( EventThreadServices& eventThreadServices,
-                           const SceneGraph::AnimatableProperty<T>& property,
-                           typename ParameterType< float >::PassingType newValue )
+template<class T>
+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 = eventThreadServices.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,
-                        &SceneGraph::AnimatableProperty<T>::BakeW,
-                        newValue );
+  new(slot) LocalType(&property,
+                      &SceneGraph::AnimatableProperty<T>::BakeW,
+                      newValue);
 }
 
 } // namespace Internal
 
 } // namespace Dali
 
-#endif // __DALI_INTERNAL_SCENE_GRAPH_ANIMATABLE_PROPERTY_H__
+#endif // DALI_INTERNAL_SCENE_GRAPH_ANIMATABLE_PROPERTY_H