Optimize some matrix multiply for projection matrix + Orthographic reflection
[platform/core/uifw/dali-core.git] / dali / internal / update / render-tasks / scene-graph-camera.h
index 2af3cec..278d765 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_SCENE_GRAPH_CAMERA_H
 
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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 <dali/internal/common/message.h>
 #include <dali/internal/common/type-abstraction-enums.h>
 #include <dali/internal/event/common/event-thread-services.h>
+#include <dali/internal/update/common/animatable-property.h>
 #include <dali/internal/update/common/double-buffered.h>
 #include <dali/internal/update/common/inherited-property.h>
+#include <dali/internal/update/nodes/node.h>
 #include <dali/public-api/actors/camera-actor.h>
 #include <dali/public-api/math/rect.h>
 
@@ -46,13 +48,12 @@ struct ParameterType<Dali::Camera::ProjectionMode>
 
 namespace SceneGraph
 {
-class Node;
 class SceneController;
 
 /**
  * Scene-graph camera object
  */
-class Camera
+class Camera : public Node
 {
 public:
   static const Dali::Camera::Type                          DEFAULT_TYPE;
@@ -60,6 +61,7 @@ public:
   static const Dali::DevelCameraActor::ProjectionDirection DEFAULT_PROJECTION_DIRECTION;
   static const bool                                        DEFAULT_INVERT_Y_AXIS;
   static const float                                       DEFAULT_FIELD_OF_VIEW;
+  static const float                                       DEFAULT_ORTHOGRAPHIC_SIZE;
   static const float                                       DEFAULT_ASPECT_RATIO;
   static const float                                       DEFAULT_LEFT_CLIPPING_PLANE;
   static const float                                       DEFAULT_RIGHT_CLIPPING_PLANE;
@@ -95,21 +97,15 @@ public:
   static Camera* New();
 
   /**
-   * Destructor
+   * Virtual destructor
    */
-  ~Camera();
+  ~Camera() override;
 
   /**
-   * Set the node this scene graph camera belongs to.
-   * @param[in] node The owning node.
+   * Overriden delete operator
+   * Deletes the camera from its global memory pool
    */
-  void SetNode(const Node* node);
-
-  /**
-   * Get the node this scene graph camera belongs to.
-   * @return node The owning node.
-   */
-  const Node* GetNode() const;
+  void operator delete(void* ptr);
 
   /**
    * @copydoc Dali::Internal::CameraActor::SetType
@@ -141,16 +137,6 @@ public:
   void SetProjectionDirection(Dali::DevelCameraActor::ProjectionDirection direction);
 
   /**
-   * @copydoc Dali::Internal::CameraActor::SetFieldOfView
-   */
-  void SetFieldOfView(float fieldOfView);
-
-  /**
-   * @copydoc Dali::Internal::CameraActor::SetAspectRatio
-   */
-  void SetAspectRatio(float aspectRatio);
-
-  /**
    * @copydoc Dali::Internal::CameraActor::SetLeftClippingPlane
    */
   void SetLeftClippingPlane(float leftClippingPlane);
@@ -191,6 +177,57 @@ public:
   void SetTargetPosition(const Vector3& targetPosition);
 
   /**
+   * @brief Bakes the field of view.
+   * @param[in] updateBufferIndex The current update buffer index.
+   * @param[in] fieldOfView The field of view.
+   */
+  void BakeFieldOfView(BufferIndex updateBufferIndex, float fieldOfView);
+
+  /**
+   * @brief Retrieve the field of view.
+   * @param[in] bufferIndex The buffer to read from.
+   * @return The field of view.
+   */
+  float GetFieldOfView(BufferIndex bufferIndex) const
+  {
+    return mFieldOfView[bufferIndex];
+  }
+
+  /**
+   * @brief Bakes the orthographic size.
+   * @param[in] updateBufferIndex The current update buffer index.
+   * @param[in] orthographicSize The orthographic size.
+   */
+  void BakeOrthographicSize(BufferIndex updateBufferIndex, float orthographicSize);
+
+  /**
+   * @brief Retrieve the orthographic size.
+   * @param[in] bufferIndex The buffer to read from.
+   * @return The orthographic size.
+   */
+  float GetOrthographicSize(BufferIndex bufferIndex) const
+  {
+    return mOrthographicSize[bufferIndex];
+  }
+
+  /**
+   * @brief Bakes the aspect ratio.
+   * @param[in] updateBufferIndex The current update buffer index.
+   * @param[in] aspectRatio The aspect ratio.
+   */
+  void BakeAspectRatio(BufferIndex updateBufferIndex, float aspectRatio);
+
+  /**
+   * @brief Retrieve the aspect ratio.
+   * @param[in] bufferIndex The buffer to read from.
+   * @return The aspect ratio.
+   */
+  float GetAspectRatio(BufferIndex bufferIndex) const
+  {
+    return mAspectRatio[bufferIndex];
+  }
+
+  /**
    * Sets the reflection plane
    * @param[in] plane reflection plane
    */
@@ -221,7 +258,7 @@ public:
    *
    * @return false if the sphere lies outside of the frustum.
    */
-  bool CheckSphereInFrustum(BufferIndex bufferIndex, const Vector3& origin, float radius);
+  bool CheckSphereInFrustum(BufferIndex bufferIndex, const Vector3& origin, float radius) const;
 
   /**
    * @brief Check to see if a bounding box lies within the view frustum.
@@ -232,7 +269,12 @@ public:
    *
    * @return false if the cubeoid lies completely outside of the frustum, true otherwise
    */
-  bool CheckAABBInFrustum(BufferIndex bufferIndex, const Vector3& origin, const Vector3& halfExtents);
+  bool CheckAABBInFrustum(BufferIndex bufferIndex, const Vector3& origin, const Vector3& halfExtents) const;
+
+  /**
+   * @brief Calculate orthographic clipping box by this camera's orthographic size.
+   */
+  Dali::Rect<int32_t> GetOrthographicClippingBox(BufferIndex bufferIndex) const;
 
   /**
    * Retrieve the projection-matrix; this is double buffered for input handling.
@@ -256,6 +298,27 @@ public:
   const Matrix& GetFinalProjectionMatrix(BufferIndex bufferIndex) const;
 
   /**
+   * Retrieve the field of view property querying interface.
+   * @pre The camera is on-stage.
+   * @return The field of view property querying interface.
+   */
+  const PropertyBase* GetFieldOfView() const;
+
+  /**
+   * Retrieve the orthographic size property querying interface.
+   * @pre The camera is on-stage.
+   * @return The orthographic size property querying interface.
+   */
+  const PropertyBase* GetOrthographicSize() const;
+
+  /**
+   * Retrieve the aspect ratio property querying interface.
+   * @pre The camera is on-stage.
+   * @return The aspect ratio property querying interface.
+   */
+  const PropertyBase* GetAspectRatio() const;
+
+  /**
    * Retrieve the projection-matrix property querying interface.
    * @pre The camera is on-stage.
    * @return The projection-matrix property querying interface.
@@ -279,7 +342,12 @@ public:
   /**
    * @return true if the view matrix of camera is updated this or the previous frame
    */
-  bool ViewMatrixUpdated();
+  bool ViewMatrixUpdated() const;
+
+  /**
+   * @return true if the projection matrix projection matrix relative properties are animated this or the previous frame
+   */
+  bool IsProjectionMatrixAnimated() const;
 
 private:
   /**
@@ -287,11 +355,11 @@ private:
    */
   Camera();
 
-  // Non copyable
-  // Undefined
-  Camera(const Camera&);
-  // Undefined
-  Camera& operator=(const Camera& rhs);
+  // Delete copy and move
+  Camera(const Camera&) = delete;
+  Camera(Camera&&)      = delete;
+  Camera& operator=(const Camera& rhs) = delete;
+  Camera& operator=(Camera&& rhs) = delete;
 
   /**
    * Recalculates the view matrix.
@@ -316,17 +384,9 @@ private:
    */
   void UpdateFrustum(BufferIndex updateBufferIndex, bool normalize = true);
 
-  /**
-   * Adjust near plane for reflection
-   * @param perspective Perspective matrix
-   * @param clipPlane Clipping plane
-   */
-  void AdjustNearPlaneForPerspective(Matrix& perspective, const Vector4& clipPlane);
-
-  uint32_t    mUpdateViewFlag;       ///< This is non-zero if the view matrix requires an update
-  uint32_t    mUpdateProjectionFlag; ///< This is non-zero if the projection matrix requires an update
-  int         mProjectionRotation;   ///< The rotaion angle of the projection
-  const Node* mNode;                 ///< The node this scene graph camera belongs to
+  uint32_t mUpdateViewFlag;       ///< This is non-zero if the view matrix requires an update
+  uint32_t mUpdateProjectionFlag; ///< This is non-zero if the projection matrix requires an update
+  int      mProjectionRotation;   ///< The rotaion angle of the projection
 
 public:                                                             // PROPERTIES
   Dali::Camera::Type                          mType;                // Non-animatable
@@ -334,12 +394,10 @@ public:                                                             // PROPERTIE
   Dali::DevelCameraActor::ProjectionDirection mProjectionDirection; // Non-animatable
   bool                                        mInvertYAxis;         // Non-animatable
 
-  float   mFieldOfView;
-  float   mAspectRatio;
-  float   mLeftClippingPlane;
-  float   mRightClippingPlane;
-  float   mTopClippingPlane;
-  float   mBottomClippingPlane;
+  AnimatableProperty<float> mFieldOfView;      // Animatable
+  AnimatableProperty<float> mOrthographicSize; // Animatable
+  AnimatableProperty<float> mAspectRatio;      // Animatable
+
   float   mNearClippingPlane;
   float   mFarClippingPlane;
   Vector3 mTargetPosition;
@@ -393,70 +451,37 @@ inline void SetProjectionDirectionMessage(EventThreadServices& eventThreadServic
   new(slot) LocalProjectionDirection(&camera, &Camera::SetProjectionDirection, parameter);
 }
 
-inline void SetFieldOfViewMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
-{
-  using LocalType = MessageValue1<Camera, float>;
-
-  // Reserve some memory inside the message queue
-  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(&camera, &Camera::SetFieldOfView, parameter);
-}
-
-inline void SetAspectRatioMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
-{
-  using LocalType = MessageValue1<Camera, float>;
-
-  // Reserve some memory inside the message queue
-  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(&camera, &Camera::SetAspectRatio, parameter);
-}
-
-inline void SetLeftClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
-{
-  using LocalType = MessageValue1<Camera, float>;
-
-  // Reserve some memory inside the message queue
-  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(&camera, &Camera::SetLeftClippingPlane, parameter);
-}
-
-inline void SetRightClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
+inline void BakeFieldOfViewMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
 {
-  using LocalType = MessageValue1<Camera, float>;
+  using LocalType = MessageDoubleBuffered1<Camera, float>;
 
   // Reserve some memory inside the message queue
   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(&camera, &Camera::SetRightClippingPlane, parameter);
+  new(slot) LocalType(&camera, &Camera::BakeFieldOfView, parameter);
 }
 
-inline void SetTopClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
+inline void BakeOrthographicSizeMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
 {
-  using LocalType = MessageValue1<Camera, float>;
+  using LocalType = MessageDoubleBuffered1<Camera, float>;
 
   // Reserve some memory inside the message queue
   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(&camera, &Camera::SetTopClippingPlane, parameter);
+  new(slot) LocalType(&camera, &Camera::BakeOrthographicSize, parameter);
 }
 
-inline void SetBottomClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
+inline void BakeAspectRatioMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
 {
-  using LocalType = MessageValue1<Camera, float>;
+  using LocalType = MessageDoubleBuffered1<Camera, float>;
 
   // Reserve some memory inside the message queue
   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(&camera, &Camera::SetBottomClippingPlane, parameter);
+  new(slot) LocalType(&camera, &Camera::BakeAspectRatio, parameter);
 }
 
 inline void SetNearClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)