Files
Upsilon/apps/shared/continuous_function_cache.h
Hugo Saint-Vignes 52f83eb682 [apps/shared] Halve k_parametricStepFactor to maximise cache hits
Change-Id: Ibe3c441e4af88277d1e4594801b805336a1f3e0b
2020-11-04 15:11:45 +01:00

60 lines
2.3 KiB
C++

#ifndef SHARED_CONTINUOUS_FUNCTION_CACHE_H
#define SHARED_CONTINUOUS_FUNCTION_CACHE_H
#include "../graph/graph/graph_view.h"
#include <ion/display.h>
#include <poincare/context.h>
#include <poincare/coordinate_2D.h>
namespace Shared {
class ContinuousFunction;
class ContinuousFunctionCache {
private:
/* The size of the cache is chosen to optimize the display of cartesian
* functions */
static constexpr int k_sizeOfCache = Ion::Display::Width;
public:
static constexpr int k_numberOfAvailableCaches = 2;
/* Parametric and polar functions require caching both x and y values,
* with the same k_sizeOfCache. To cover the entire range,
* k_numberOfParametricCacheablePoints is halved. */
static constexpr int k_numberOfParametricCacheablePoints = k_sizeOfCache / 2;
static void PrepareForCaching(void * fun, ContinuousFunctionCache * cache, float tMin, float tStep);
ContinuousFunctionCache() { clear(); }
float step() const { return m_tStep; }
void clear();
Poincare::Coordinate2D<float> valueForParameter(const ContinuousFunction * function, Poincare::Context * context, float t);
private:
/* We need a certain amount of tolerance since we try to evaluate the
* equality of floats. But the value has to be chosen carefully. Too high of
* a tolerance causes false positives, which lead to errors in curves
* (ex : 1/x with a vertical line at 0). Too low of a tolerance causes false
* negatives, which slows down the drawing.
*
* The value 128*FLT_EPSILON has been found to be the lowest for which all
* indices verify indexForParameter(tMin + index * tStep) = index. */
static constexpr float k_cacheHitTolerance = 128.0f * FLT_EPSILON;
void invalidateBetween(int iInf, int iSup);
void setRange(ContinuousFunction * function, float tMin, float tStep);
int indexForParameter(const ContinuousFunction * function, float t) const;
Poincare::Coordinate2D<float> valuesAtIndex(const ContinuousFunction * function, Poincare::Context * context, float t, int i);
void pan(ContinuousFunction * function, float newTMin);
float m_tMin, m_tStep;
float m_cache[k_sizeOfCache];
/* m_startOfCache is used to implement a circular buffer for easy panning
* with cartesian functions. When dealing with parametric or polar functions,
* m_startOfCache should be zero.*/
int m_startOfCache;
};
}
#endif