Purge underscored header file barriers
[platform/core/uifw/dali-core.git] / dali / internal / update / gestures / scene-graph-pan-gesture.h
1 #ifndef DALI_INTERNAL_SCENE_GRAPH_PAN_GESTURE_H
2 #define DALI_INTERNAL_SCENE_GRAPH_PAN_GESTURE_H
3
4 /*
5  * Copyright (c) 2019 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // INTERNAL INCLUDES
22 #include <dali/devel-api/threading/mutex.h>
23 #include <dali/public-api/common/vector-wrapper.h>
24 #include <dali/public-api/events/pan-gesture.h>
25 #include <dali/internal/update/common/property-owner.h>
26 #include <dali/internal/update/gestures/gesture-properties.h>
27
28 namespace Dali
29 {
30
31 struct PanGesture;
32
33 namespace Internal
34 {
35
36 struct PanGestureProfiling;
37
38 namespace SceneGraph
39 {
40
41 /**
42  * The latest pan gesture information is stored in this scene object.
43  */
44 class PanGesture : public PropertyOwner
45 {
46 public:
47
48   enum PredictionMode
49   {
50     PREDICTION_NONE = 0,
51     PREDICTION_1,
52     PREDICTION_2,
53   };
54
55   enum SmoothingMode
56   {
57     SMOOTHING_NONE,           // No smoothing.
58     SMOOTHING_LAST_VALUE,     // Smooth between last value and latest value.
59     SMOOTHING_MULTI_TAP,      // Uses multitap smoothing, only available with Prediction mode 2.
60   };
61
62   static const PredictionMode DEFAULT_PREDICTION_MODE;
63   static const int NUM_PREDICTION_MODES;
64
65   static const SmoothingMode DEFAULT_SMOOTHING_MODE;
66   static const int NUM_SMOOTHING_MODES;
67
68   // Latest Pan Information
69
70   /**
71    * Only stores the information we actually require from Dali::PanGesture
72    */
73   struct PanInfo
74   {
75     /**
76      * Stores the velocity, displacement and position.
77      */
78     struct Info
79     {
80       Info()
81       {
82       }
83
84       /**
85        * Copy constructor
86        */
87       Info( const Info& rhs )
88       : velocity( rhs.velocity ),
89         displacement( rhs.displacement ),
90         position( rhs.position )
91       {
92       }
93
94       /**
95        * Assignment operator
96        */
97       Info& operator=( const Info& rhs )
98       {
99         if( this != &rhs )
100         {
101           velocity = rhs.velocity;
102           displacement = rhs.displacement;
103           position = rhs.position;
104         }
105
106         return *this;
107       }
108
109       // Data
110
111       Vector2 velocity;
112       Vector2 displacement;
113       Vector2 position;
114     };
115
116     /**
117      * Constructor
118      */
119     PanInfo()
120     : time( 0u ),
121       state( Gesture::Clear ),
122       read( true )
123     {
124     }
125
126     /**
127      * Copy constructor
128      */
129     PanInfo( const PanInfo& rhs )
130     : time( rhs.time ),
131       state( rhs.state ),
132       local( rhs.local ),
133       screen( rhs.screen ),
134       read( true )
135     {
136     }
137
138     /**
139      * Assignment operator
140      */
141     PanInfo& operator=( const PanInfo& rhs )
142     {
143       if( this != &rhs )
144       {
145         time = rhs.time;
146         state = rhs.state;
147         local = rhs.local;
148         screen = rhs.screen;
149         read = rhs.read;
150       }
151
152       return *this;
153     }
154
155     /**
156      * Assignment operator
157      * @param[in] gesture A Dali::Gesture
158      */
159     PanInfo& operator=( const Dali::PanGesture& rhs )
160     {
161       time = rhs.time;
162       state = rhs.state;
163
164       local.velocity = rhs.velocity;
165       local.displacement = rhs.displacement;
166       local.position = rhs.position;
167
168       screen.velocity = rhs.screenVelocity;
169       screen.displacement = rhs.screenDisplacement;
170       screen.position = rhs.screenPosition;
171
172       return *this;
173     }
174
175     // Data
176     unsigned int time;
177     Gesture::State state;
178     Info local;
179     Info screen;
180     volatile bool read;
181   };
182
183   typedef std::vector<PanInfo> PanInfoHistory;
184   typedef PanInfoHistory::iterator PanInfoHistoryIter;
185   typedef PanInfoHistory::const_iterator PanInfoHistoryConstIter;
186
187 private:
188   static const unsigned int PAN_GESTURE_HISTORY = 30u;
189
190 public:
191
192   /**
193    * Create a new PanGesture
194    */
195   static PanGesture* New();
196
197   /**
198    * Virtual destructor
199    */
200   virtual ~PanGesture();
201
202   /**
203    * Adds a PanGesture to the internal circular-buffer waiting to be handled by UpdateProperties.
204    * @param[in]  gesture  The latest pan gesture.
205    */
206   void AddGesture( const Dali::PanGesture& gesture );
207
208   /**
209    * @brief Removes pan events from the history that are older than maxAge, leaving at least minEvents
210    *
211    * @param[in] panHistory The pan event history container
212    * @param[in] currentTime The current frame time
213    * @param[in] maxAge Maximum age of an event before removing (in millis)
214    * @param[in] minEvents The minimum number of events to leave in history, oldest events are removed before newest
215    */
216   void RemoveOldHistory(PanInfoHistory& panHistory, unsigned int currentTime, unsigned int maxAge, unsigned int minEvents);
217
218   /**
219    * Uses elapsed time and time stamps
220    */
221   void PredictionMode1(int eventsThisFrame, PanInfo& gestureOut, PanInfoHistory& panHistory, unsigned int lastVSyncTime, unsigned int nextVSyncTime);
222
223   /**
224    * Blends two points together.
225    * The blend value ranges are:
226    * 0.0f = use 100% of current value.
227    * 1.0f = use half-way average of current and last value.
228    *
229    * @param[in,out] gesture     Pass in current gesture, outputs result of blend.
230    * @param[in]     lastGesture Pass in gesture to blend between.
231    */
232   void BlendPoints( PanInfo& gesture, PanInfo& lastGesture, float blendValue );
233
234   /**
235    * Called by the update manager so that we can update the value of our properties.
236    * @param[in]  nextRenderTime  The estimated time of the next render (in milliseconds).
237    * @return true, if properties were updated.
238    */
239   bool UpdateProperties( unsigned int lastRenderTime, unsigned int nextRenderTime );
240
241   /**
242    * Retrieves a reference to the panning flag property.
243    * @return The panning flag property.
244    */
245   const GesturePropertyBool& GetPanningProperty() const;
246
247   /**
248    * Retrieves a reference to the screen position property.
249    * @return The screen position property.
250    */
251   const GesturePropertyVector2& GetScreenPositionProperty() const;
252
253   /**
254    * Retrieves a reference to the screen velocity property.
255    * @return The screen velocity property.
256    */
257   const GesturePropertyVector2& GetScreenVelocityProperty() const;
258
259   /**
260    * Retrieves a reference to the screen displacement property.
261    * @return The screen displacement property.
262    */
263   const GesturePropertyVector2& GetScreenDisplacementProperty() const;
264
265   /**
266    * Retrieves a reference to the local position property.
267    * @return The local position property.
268    */
269   const GesturePropertyVector2& GetLocalPositionProperty() const;
270
271   /**
272    * Retrieves a reference to the local displacement property.
273    * @return The local displacement property.
274    */
275   const GesturePropertyVector2& GetLocalDisplacementProperty() const;
276
277   /**
278    * Retrieves a reference to the local velocity property.
279    * @return The local velocity property.
280    */
281   const GesturePropertyVector2& GetLocalVelocityProperty() const;
282
283   /**
284    * @brief Sets the prediction mode of the pan gesture
285    *
286    * @param[in] mode The prediction mode
287    */
288   void SetPredictionMode(PredictionMode mode);
289
290   /**
291    * @brief Sets the prediction amount of the pan gesture
292    *
293    * @param[in] amount The prediction amount in milliseconds
294    */
295   void SetPredictionAmount(unsigned int amount);
296
297   /**
298    * @brief Sets the upper bound of the prediction amount for clamping
299    *
300    * @param[in] amount The prediction amount in milliseconds
301    */
302   void SetMaximumPredictionAmount(unsigned int amount);
303
304   /**
305    * @brief Sets the lower bound of the prediction amount for clamping
306    *
307    * @param[in] amount The prediction amount in milliseconds
308    */
309   void SetMinimumPredictionAmount(unsigned int amount);
310
311   /**
312    * @brief Sets the amount of prediction interpolation to adjust when the pan velocity is changed
313    *
314    * @param[in] amount The prediction amount in milliseconds
315    */
316   void SetPredictionAmountAdjustment(unsigned int amount);
317
318   /**
319    * @brief Sets the prediction mode of the pan gesture
320    *
321    * @param[in] mode The prediction mode
322    */
323   void SetSmoothingMode(SmoothingMode mode);
324
325   /**
326    * @brief Sets the amount of smoothing to apply for the current smoothing mode
327    *
328    * @param[in] amount The amount of smoothing [0.0f,1.0f]
329    */
330   void SetSmoothingAmount(float amount);
331
332   /*
333    * @brief Sets whether to use actual times of the real gesture and frames or not.
334    *
335    * @param[in] value True = use actual times, False = use perfect values
336    */
337   void SetUseActualTimes( bool value );
338
339   /**
340    * @brief Sets the interpolation time range (ms) of past points to use (with weights) when interpolating.
341    *
342    * @param[in] value Time range in ms
343    */
344   void SetInterpolationTimeRange( int value );
345
346   /**
347    * @brief Sets whether to use scalar only prediction, which when enabled, ignores acceleration.
348    *
349    * @param[in] value True = use scalar prediction only
350    */
351   void SetScalarOnlyPredictionEnabled( bool value );
352
353   /**
354    * @brief Sets whether to use two point prediction. This combines two interpolated points to get more steady acceleration and velocity values.
355    *
356    * @param[in] value True = use two point prediction
357    */
358   void SetTwoPointPredictionEnabled( bool value );
359
360   /**
361    * @brief Sets the time in the past to interpolate the second point when using two point interpolation.
362    *
363    * @param[in] value Time in past in ms
364    */
365   void SetTwoPointInterpolatePastTime( int value );
366
367   /**
368    * @brief Sets the two point velocity bias. This is the ratio of first and second points to use for velocity.
369    *
370    * @param[in] value 0.0f = 100% first point. 1.0f = 100% of second point.
371    */
372   void SetTwoPointVelocityBias( float value );
373
374   /**
375    * @brief Sets the two point acceleration bias. This is the ratio of first and second points to use for acceleration.
376    *
377    * @param[in] value 0.0f = 100% first point. 1.0f = 100% of second point.
378    */
379   void SetTwoPointAccelerationBias( float value );
380
381   /**
382    * @brief Sets the range of time (ms) of points in the history to perform multitap smoothing with (if enabled).
383    *
384    * @param[in] value Time in past in ms
385    */
386   void SetMultitapSmoothingRange( int value );
387
388   /**
389    * Called to provide pan-gesture profiling information.
390    */
391   void EnableProfiling();
392
393   /**
394    * Reset default properties, custom ones not supported due to this being the only object in scene side
395    * @param updateBufferIndex index to use
396    */
397   void ResetDefaultProperties( BufferIndex updateBufferIndex );
398
399 private:
400
401   /**
402    * Protected constructor.
403    */
404   PanGesture();
405
406   // Undefined
407   PanGesture(const PanGesture&);
408
409 private:
410
411   // Struct to keep pairs of local and screen data together.
412   // TODO: This can encapsulate some functionality also.
413   typedef struct
414   {
415     Vector2 local;
416     Vector2 screen;
417   } RelativeVectors;
418
419   /**
420    * Houses new code to process input events and generate an output point.
421    *
422    * @param[in]  lastVSyncTime The time of the last render (in milliseconds)
423    * @param[in]  nextVSyncTime The estimated time of the next render (in milliseconds)
424    */
425   bool NewAlgorithm( unsigned int lastVSyncTime, unsigned int nextVSyncTime );
426
427   /**
428    * Gets the (absolute) time difference between two times.
429    * This is limited by minimumDelta, so it can be safe to use as a divisor.
430    * This function is wrapped so that the behviour can be overridden to return a "perfect" time difference (overrideDifference).
431    *
432    * @param[in]  timeA The first time to calculate from
433    * @param[in]  timeB The second time to calculate from
434    * @param[in]  minimumDelta The smallest amount the difference can become
435    * @param[in]  overrideDifference The time difference to return if using perfect times
436    */
437   inline float GetDivisibleTimeDifference( int timeA, int timeB, float minimumDelta, float overrideDifference );
438
439   /**
440    * This limits the change currentAcceleration can have over lastAcceleration by the specified changeLimit value.
441    *
442    * @param[in]  currentAcceleration The acceleration to modify
443    * @param[in]  lastAcceleration The acceleration to limit against
444    * @param[in]  changeLimit The maximum change (in either direction)
445    */
446   void LimitAccelerationChange( RelativeVectors& currentAcceleration, RelativeVectors& lastAcceleration, float changeLimit );
447
448   /**
449    * Reads all events received this frame into a linear buffer.
450    * A lock is held while this is done.
451    */
452   unsigned int ReadFrameEvents();
453
454   /**
455    * Converts between input rate and internal rate (typically 60Hz internally).
456    * Also writes to the pan history container.
457    * TODO: Does not need to return the gesture if it is in the history also, but currently it's used.
458    * (if rate conversion does not generate a point there are points still in history, but this can been done with a bool property).
459    *
460    * @param[out] rateConvertedGesture Result gesture for this frame is writen here.
461    * @param[in]  eventsThisFrame Number of events to convert
462    * @param[in]  currentFrameTime Time of the frame we will render to
463    * @param[in]  lastFrameTime Time of the last rendered frame
464    * @param[out] justStarted Set to true if we are now starting a new gesture
465    * @param[out] justFinished Set to true if we are now finishing a gesture
466    */
467   bool InputRateConversion( PanInfo& rateConvertedGesture, unsigned int eventsThisFrame,
468       unsigned int currentFrameTime, unsigned int lastFrameTime, bool& justStarted, bool& justFinished );
469
470   /**
471    * Generates an interpolated point at the specified point in time.
472    *
473    * @param[in]  history of points to use
474    * @param[in]  currentTime Time of the frame we will render to
475    * @param[in]  targetTime Time of the point to generate
476    * @param[in]  range Range of time (each side of target time) to use points from
477    * @param[out] outPoint Generated point
478    * @param[out] acceleration Generated acceleration
479    * @param[in]  outputTimeGranularity Time difference between output point (typically 60Hz)
480    * @param[in]  eraseUnused Set to true to clean up any history not used by the function
481    */
482   bool InterpolatePoint( PanInfoHistory& history, unsigned int currentTime, unsigned int targetTime, unsigned int range,
483       PanInfo& outPoint, RelativeVectors& acceleration, int outputTimeGranularity, bool eraseUnused );
484
485   /**
486    * Predicts a point in the future, based on the supplied point and acceleration.
487    * Other user configuration settings are considered.
488    *
489    * @param[in] startPoint Starting point to use. Position and velocity are taken from here.
490    * @param[in] accelerationToUse The acceleration to use.
491    * @param[out] predictedPoint Generated predicted point
492    * @param[in]  currentFrameTime Time of the frame we will render to
493    * @param[in]  previousFrameTime Time of the last rendered frame
494    * @param[in]  noPreviousData Set to true if we are just starting a gesture
495    */
496   void PredictionMode2( PanInfo& startPoint, RelativeVectors& accelerationToUse,
497       PanInfo& predictedPoint, unsigned int currentFrameTime, unsigned int previousFrameTime, bool noPreviousData );
498
499 private:
500
501   // Undefined
502   PanGesture& operator=(const PanGesture&);
503
504   // Defines information to be gathered by the gesture reading code.
505   struct FrameGestureInfo
506   {
507     PanGesture::PanInfo frameGesture;
508     float acceleration;
509     unsigned int eventsThisFrame;
510     bool justStarted;
511     bool justFinished;
512
513     FrameGestureInfo()
514     : acceleration( 0.0f ),
515       eventsThisFrame( 0 ),
516       justStarted( false ),
517       justFinished( false )
518     {
519     }
520   };
521
522   /**
523    * Reads gestures from input, builds history.
524    * @param[out] info Written to with information about gestures read this frame.
525    * @param[in] currentTimestamp The time of this frame.
526    */
527   bool ReadGestures( FrameGestureInfo& info, unsigned int currentTimestamp );
528
529   /**
530    * Reads gestures from input and resamples data, builds history.
531    * @param[out] info Written to with information about gestures read this frame.
532    * @param[in] currentTimestamp The time of this frame.
533    */
534   bool ReadAndResampleGestures( FrameGestureInfo& info, unsigned int currentTimestamp );
535
536 private:
537
538   // Properties
539   GesturePropertyBool    mPanning;            ///< panning flag
540   GesturePropertyVector2 mScreenPosition;     ///< screenPosition
541   GesturePropertyVector2 mScreenDisplacement; ///< screenDisplacement
542   GesturePropertyVector2 mScreenVelocity;     ///< screenVelocity
543   GesturePropertyVector2 mLocalPosition;      ///< localPosition
544   GesturePropertyVector2 mLocalDisplacement;  ///< localDisplacement
545   GesturePropertyVector2 mLocalVelocity;      ///< localVelocity
546
547   PanInfoHistory mPanHistory;
548   PanInfoHistory mPredictionHistory;
549   PanInfo mGestures[PAN_GESTURE_HISTORY];     ///< Circular buffer storing the 4 most recent gestures.
550   PanInfo mReadGestures[PAN_GESTURE_HISTORY]; ///< Linear buffer storing the most recent gestures (to reduce read lock time).
551   PanInfo mLastGesture;                       ///< The last gesture. (last update frame).
552   PanInfo mTargetGesture;                     ///< The most recent input gesture, if the current used gesture does not match.
553   PanInfo mLastUnmodifiedGesture;             ///< The last gesture before any processing was done on it.
554   PanInfo mLastSecondInterpolatedPoint;       ///< Stores the last second interpolated point we generated.
555   PanInfo mLastFrameReadGesture;              ///< Stores the last gesture read.
556   PanInfo mLastPredictedPoint;                ///< Stores the last predicted point we generated.
557   RelativeVectors mLastAcceleration;          ///< Stores the acceleration value from the acceleration limiting last frame.
558   RelativeVectors mLastInterpolatedAcceleration;  ///< Stores the second interpolated point acceleration value from the last frame.
559   RelativeVectors mLastInitialAcceleration;   ///< Stores the initial acceleration value from the last frame.
560
561   volatile unsigned int mWritePosition;       ///< The next PanInfo buffer to write to. (starts at 0).
562   unsigned int mReadPosition;                 ///< The next PanInfo buffer to read. (starts at 0).
563   bool mNotAtTarget;                          ///< Keeps track of if the last gesture used was the most recent received.
564   bool mInGesture;                            ///< True if the gesture is currently being handled i.e. between Started <-> Finished/Cancelled.
565   bool mPredictionAmountOverridden;
566   bool mSmoothingAmountOverridden;
567
568   PanGestureProfiling* mProfiling;            ///< NULL unless pan-gesture profiling information is required.
569   Dali::Mutex mMutex;                         ///< Mutex to lock access.
570
571   // Environment variables:
572
573   PredictionMode mPredictionMode;             ///< The pan gesture prediction mode
574   unsigned int mPredictionAmount;             ///< how far into future to predict in milliseconds
575   unsigned int mCurrentPredictionAmount;      ///< the current prediction amount used by the prediction algorithm
576   unsigned int mMaxPredictionAmount;          ///< the maximum prediction amount used by the prediction algorithm
577   unsigned int mMinPredictionAmount;          ///< the minimum prediction amount used by the prediction algorithm
578   unsigned int mPredictionAmountAdjustment;   ///< the prediction amount to adjust in milliseconds when pan velocity changes
579   SmoothingMode mSmoothingMode;               ///< The pan gesture prediction mode
580   float         mSmoothingAmount;             ///< How much smoothing to apply [0.0f,1.0f]
581   bool mUseActualTimes;                       ///< Disable to optionally override actual times if they make results worse.
582   int mInterpolationTimeRange;                ///< Time into past history (ms) to use points to interpolate the first point.
583   bool mScalarOnlyPredictionEnabled;          ///< If enabled, prediction is done using velocity alone (no integration or acceleration).
584   bool mTwoPointPredictionEnabled;            ///< If enabled, a second interpolated point is predicted and combined with the first to get more stable values.
585   int mTwoPointPastInterpolateTime;           ///< The target time in the past to generate the second interpolated point.
586   float mTwoPointVelocityBias;                ///< The ratio of first and second interpolated points to use for velocity. 0.0f = 100% of first point. 1.0f = 100% of second point.
587   float mTwoPointAccelerationBias;            ///< The ratio of first and second interpolated points to use for acceleration. 0.0f = 100% of first point. 1.0f = 100% of second point.
588   int mMultiTapSmoothingRange;                ///< The range in time (ms) of points in the history to smooth the final output against.
589 };
590
591 } // namespace SceneGraph
592
593 } // namespace Internal
594
595 } // namespace Dali
596
597 #endif // DALI_INTERNAL_SCENE_GRAPH_PAN_GESTURE_H