Eliminate allocs - Matrix and Path buffers (#1892)

Created buffers for short lived Matrix and Path objects, resetting them instead of instantiating new ones.  Also created some matrix transform methods that accept output Matrix objects to facilitate caching.
This commit is contained in:
Tony Patino 2016-06-28 17:22:48 -07:00
parent d946f3e3ff
commit 56cfd2b42b
14 changed files with 131 additions and 60 deletions

View file

@ -590,6 +590,7 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
* VIEWPORT
*/
protected Matrix mZoomInMatrixBuffer = new Matrix();
/**
* Zooms in by 1.4f, into the charts center. center.
*/
@ -597,8 +598,8 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
MPPointF center = mViewPortHandler.getContentCenter();
Matrix save = mViewPortHandler.zoomIn(center.x, -center.y);
mViewPortHandler.refresh(save, this, false);
mViewPortHandler.zoomIn(center.x, -center.y, mZoomInMatrixBuffer);
mViewPortHandler.refresh(mZoomInMatrixBuffer, this, false);
MPPointF.recycleInstance(center);
@ -609,6 +610,7 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
postInvalidate();
}
protected Matrix mZoomOutMatrixBuffer = new Matrix();
/**
* Zooms out by 0.7f, from the charts center. center.
*/
@ -616,8 +618,8 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
MPPointF center = mViewPortHandler.getContentCenter();
Matrix save = mViewPortHandler.zoomOut(center.x, -center.y);
mViewPortHandler.refresh(save, this, false);
mViewPortHandler.zoomOut(center.x, -center.y, mZoomOutMatrixBuffer);
mViewPortHandler.refresh(mZoomOutMatrixBuffer, this, false);
MPPointF.recycleInstance(center);
@ -628,6 +630,7 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
postInvalidate();
}
protected Matrix mZoomMatrixBuffer = new Matrix();
/**
* Zooms in or out by the given scale factor. x and y are the coordinates
* (in pixels) of the zoom center.
@ -638,7 +641,8 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
* @param y
*/
public void zoom(float scaleX, float scaleY, float x, float y) {
Matrix save = mViewPortHandler.zoom(scaleX, scaleY, x, y);
Matrix save = mZoomMatrixBuffer;
mViewPortHandler.zoom(scaleX, scaleY, x, y, save);
mViewPortHandler.refresh(save, this, false);
// Range might have changed, which means that Y-axis labels
@ -694,12 +698,14 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
}
}
protected Matrix mFitScreenMatrixBuffer = new Matrix();
/**
* Resets all zooming and dragging and makes the chart fit exactly it's
* bounds.
*/
public void fitScreen() {
Matrix save = mViewPortHandler.fitScreen();
Matrix save = mFitScreenMatrixBuffer;
mViewPortHandler.fitScreen(save);
mViewPortHandler.refresh(save, this, false);
calculateOffsets();

View file

@ -40,13 +40,15 @@ public class AnimatedZoomJob extends AnimatedViewPortJob implements Animator.Ani
this.xAxisRange = xAxisRange;
}
protected Matrix mOnAnimationUpdateMatrixBuffer = new Matrix();
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float scaleX = xOrigin + (xValue - xOrigin) * phase;
float scaleY = yOrigin + (yValue - yOrigin) * phase;
Matrix save = mViewPortHandler.setZoom(scaleX, scaleY);
Matrix save = mOnAnimationUpdateMatrixBuffer;
mViewPortHandler.setZoom(scaleX, scaleY, save);
mViewPortHandler.refresh(save, view, false);
float valsInView = yAxis.mAxisRange / mViewPortHandler.getScaleY();
@ -57,7 +59,7 @@ public class AnimatedZoomJob extends AnimatedViewPortJob implements Animator.Ani
mTrans.pointValuesToPixel(pts);
save = mViewPortHandler.translate(pts);
mViewPortHandler.translate(pts, save);
mViewPortHandler.refresh(save, view, true);
}

View file

@ -27,10 +27,12 @@ public class ZoomJob extends ViewPortJob {
this.axisDependency = axis;
}
protected Matrix mRunMatrixBuffer = new Matrix();
@Override
public void run() {
Matrix save = mViewPortHandler.zoom(scaleX, scaleY);
Matrix save = mRunMatrixBuffer;
mViewPortHandler.zoom(scaleX, scaleY, save);
mViewPortHandler.refresh(save, view, false);
float valsInView = ((BarLineChartBase) view).getDeltaY(axisDependency) / mViewPortHandler.getScaleY();
@ -41,7 +43,7 @@ public class ZoomJob extends ViewPortJob {
mTrans.pointValuesToPixel(pts);
save = mViewPortHandler.translate(pts);
mViewPortHandler.translate(pts, save);
mViewPortHandler.refresh(save, view, false);
((BarLineChartBase) view).calculateOffsets();

View file

@ -431,6 +431,7 @@ public class LineChartRenderer extends LineRadarRenderer {
}
}
protected Path mGenerateFilledPathBuffer = new Path();
/**
* Generates the path that is used for filled drawing.
*
@ -443,7 +444,8 @@ public class LineChartRenderer extends LineRadarRenderer {
float phaseY = mAnimator.getPhaseY();
final boolean isDrawSteppedEnabled = dataSet.getMode() == LineDataSet.Mode.STEPPED;
Path filled = new Path();
Path filled = mGenerateFilledPathBuffer;
filled.reset();
Entry entry = dataSet.getEntryForIndex(bounds.min);
filled.moveTo(entry.getX(), fillMin);

View file

@ -649,6 +649,7 @@ public class PieChartRenderer extends DataRenderer {
}
}
protected Path mDrawCenterTextPathBuffer = new Path();
/**
* draws the description text in the center of the pie chart makes most
* sense when center-hole is enabled
@ -705,7 +706,8 @@ public class PieChartRenderer extends DataRenderer {
c.save();
if (Build.VERSION.SDK_INT >= 18) {
Path path = new Path();
Path path = mDrawCenterTextPathBuffer;
path.reset();
path.addOval(holeRect, Path.Direction.CW);
c.clipPath(path);
}

View file

@ -70,6 +70,7 @@ public class RadarChartRenderer extends LineRadarRenderer {
}
}
protected Path mDrawDataSetSurfacePathBuffer = new Path();
/**
* Draws the RadarDataSet
*
@ -90,7 +91,8 @@ public class RadarChartRenderer extends LineRadarRenderer {
MPPointF center = mChart.getCenterOffsets();
MPPointF pOut = MPPointF.getInstance(0,0);
Path surface = new Path();
Path surface = mDrawDataSetSurfacePathBuffer;
surface.reset();
boolean hasMovedToPoint = false;
@ -321,6 +323,7 @@ public class RadarChartRenderer extends LineRadarRenderer {
MPPointF.recycleInstance(pOut);
}
protected Path mDrawHighlightCirclePathBuffer = new Path();
public void drawHighlightCircle(Canvas c,
MPPointF point,
float innerRadius,
@ -334,7 +337,8 @@ public class RadarChartRenderer extends LineRadarRenderer {
innerRadius = Utils.convertDpToPixel(innerRadius);
if (fillColor != ColorTemplate.COLOR_NONE) {
Path p = new Path();
Path p = mDrawHighlightCirclePathBuffer;
p.reset();
p.addCircle(point.x, point.y, outerRadius, Path.Direction.CW);
if (innerRadius > 0.f) {
p.addCircle(point.x, point.y, innerRadius, Path.Direction.CCW);

View file

@ -233,7 +233,7 @@ public class XAxisRenderer extends AxisRenderer {
protected void drawLabel(Canvas c, String formattedLabel, float x, float y, MPPointF anchor, float angleDegrees) {
Utils.drawXAxisValue(c, formattedLabel, x, y, mAxisLabelPaint, anchor, angleDegrees);
}
protected Path mRenderGridLinesPath = new Path();
protected float[] mRenderGridLinesBuffer = new float[2];
@Override
public void renderGridLines(Canvas c) {
@ -255,7 +255,8 @@ public class XAxisRenderer extends AxisRenderer {
setupGridPaint();
Path gridLinePath = new Path();
Path gridLinePath = mRenderGridLinesPath;
gridLinePath.reset();
for (int i = 0; i < positions.length; i += 2) {

View file

@ -203,6 +203,7 @@ public class XAxisRendererHorizontalBarChart extends XAxisRenderer {
}
}
protected Path mRenderLimitLinesPathBuffer = new Path();
/**
* Draws the LimitLines associated with this axis to the screen.
* This is the standard YAxis renderer using the XAxis limit lines.
@ -221,7 +222,8 @@ public class XAxisRendererHorizontalBarChart extends XAxisRenderer {
pts[0] = 0;
pts[1] = 0;
Path limitLinePath = new Path();
Path limitLinePath = mRenderLimitLinesPathBuffer;
limitLinePath.reset();
for (int i = 0; i < limitLines.size(); i++) {

View file

@ -125,6 +125,7 @@ public class YAxisRenderer extends AxisRenderer {
}
}
protected Path mRenderGridLinesPath = new Path();
@Override
public void renderGridLines(Canvas c) {
@ -139,7 +140,8 @@ public class YAxisRenderer extends AxisRenderer {
mGridPaint.setStrokeWidth(mYAxis.getGridLineWidth());
mGridPaint.setPathEffect(mYAxis.getGridDashPathEffect());
Path gridLinePath = new Path();
Path gridLinePath = mRenderGridLinesPath;
gridLinePath.reset();
// draw the grid
for (int i = 0; i < positions.length; i += 2) {
@ -194,6 +196,7 @@ public class YAxisRenderer extends AxisRenderer {
return positions;
}
protected Path mDrawZeroLinePath = new Path();
/**
* Draws the zero line.
*/
@ -205,7 +208,8 @@ public class YAxisRenderer extends AxisRenderer {
mZeroLinePaint.setColor(mYAxis.getZeroLineColor());
mZeroLinePaint.setStrokeWidth(mYAxis.getZeroLineWidth());
Path zeroLinePath = new Path();
Path zeroLinePath = mDrawZeroLinePath;
zeroLinePath.reset();
zeroLinePath.moveTo(mViewPortHandler.contentLeft(), (float) pos.y - 1);
zeroLinePath.lineTo(mViewPortHandler.contentRight(), (float) pos.y - 1);
@ -214,6 +218,7 @@ public class YAxisRenderer extends AxisRenderer {
c.drawPath(zeroLinePath, mZeroLinePaint);
}
protected Path mRenderLimitLines = new Path();
protected float[] mRenderLimitLinesBuffer = new float[2];
/**
* Draws the LimitLines associated with this axis to the screen.
@ -231,7 +236,8 @@ public class YAxisRenderer extends AxisRenderer {
float[] pts = mRenderLimitLinesBuffer;
pts[0] = 0;
pts[1] = 0;
Path limitLinePath = new Path();
Path limitLinePath = mRenderLimitLines;
limitLinePath.reset();
for (int i = 0; i < limitLines.size(); i++) {

View file

@ -173,6 +173,8 @@ public class YAxisRendererHorizontalBarChart extends YAxisRenderer {
return p;
}
protected Path mDrawZeroLinePathBuffer = new Path();
@Override
protected void drawZeroLine(Canvas c) {
@ -182,7 +184,8 @@ public class YAxisRendererHorizontalBarChart extends YAxisRenderer {
mZeroLinePaint.setColor(mYAxis.getZeroLineColor());
mZeroLinePaint.setStrokeWidth(mYAxis.getZeroLineWidth());
Path zeroLinePath = new Path();
Path zeroLinePath = mDrawZeroLinePathBuffer;
zeroLinePath.reset();
zeroLinePath.moveTo((float) pos.x - 1, mViewPortHandler.contentTop());
zeroLinePath.lineTo((float) pos.x - 1, mViewPortHandler.contentBottom());
@ -191,6 +194,7 @@ public class YAxisRendererHorizontalBarChart extends YAxisRenderer {
c.drawPath(zeroLinePath, mZeroLinePaint);
}
protected Path mRenderLimitLinesPathBuffer = new Path();
protected float[] mRenderLimitLinesBuffer = new float[4];
/**
* Draws the LimitLines associated with this axis to the screen.
@ -211,7 +215,8 @@ public class YAxisRendererHorizontalBarChart extends YAxisRenderer {
pts[1] = 0;
pts[2] = 0;
pts[3] = 0;
Path limitLinePath = new Path();
Path limitLinePath = mRenderLimitLinesPathBuffer;
limitLinePath.reset();
for (int i = 0; i < limitLines.size(); i++) {

View file

@ -174,6 +174,7 @@ public class YAxisRendererRadarChart extends YAxisRenderer {
MPPointF.recycleInstance(pOut);
}
private Path mRenderLimitLinesPathBuffer = new Path();
@Override
public void renderLimitLines(Canvas c) {
@ -203,7 +204,8 @@ public class YAxisRendererRadarChart extends YAxisRenderer {
float r = (l.getLimit() - mChart.getYChartMin()) * factor;
Path limitPath = new Path();
Path limitPath = mRenderLimitLinesPathBuffer;
limitPath.reset();
for (int j = 0; j < mChart.getData().getMaxEntryCountSet().getEntryCount(); j++) {

View file

@ -16,6 +16,7 @@ import com.github.mikephil.charting.utils.ViewPortHandler;
*/
public class TriangleShapeRenderer implements ShapeRenderer {
protected Path mTrianglePathBuffer = new Path();
@Override
public void renderShape(Canvas c, IScatterDataSet dataSet, ViewPortHandler viewPortHandler, ScatterBuffer buffer, Paint
@ -31,7 +32,8 @@ public class TriangleShapeRenderer implements ShapeRenderer {
renderPaint.setStyle(Paint.Style.FILL);
// create a triangle path
Path tri = new Path();
Path tri = mTrianglePathBuffer;
tri.reset();
for (int i = 0; i < buffer.size(); i += 2) {

View file

@ -356,6 +356,7 @@ public class Transformer {
m.mapRect(rects.get(i));
}
protected Matrix mPixelsToValueMatrixBuffer = new Matrix();
/**
* Transforms the given array of touch positions (pixels) (x, y, x, y, ...)
* into values on the chart.
@ -364,7 +365,8 @@ public class Transformer {
*/
public void pixelsToValue(float[] pixels) {
Matrix tmp = new Matrix();
Matrix tmp = mPixelsToValueMatrixBuffer;
tmp.reset();
// invert all matrixes to convert back to the original value
mMatrixOffset.invert(tmp);

View file

@ -198,13 +198,16 @@ public class ViewPortHandler {
public Matrix zoomIn(float x, float y) {
Matrix save = new Matrix();
save.set(mMatrixTouch);
save.postScale(1.4f, 1.4f, x, y);
zoomIn(x,y,save);
return save;
}
public void zoomIn(float x, float y, Matrix outputMatrix){
outputMatrix.reset();
outputMatrix.set(mMatrixTouch);
outputMatrix.postScale(1.4f, 1.4f, x, y);
}
/**
* Zooms out by 0.7f, x and y are the coordinates (in pixels) of the zoom
* center.
@ -212,13 +215,16 @@ public class ViewPortHandler {
public Matrix zoomOut(float x, float y) {
Matrix save = new Matrix();
save.set(mMatrixTouch);
save.postScale(0.7f, 0.7f, x, y);
zoomOut(x,y,save);
return save;
}
public void zoomOut(float x, float y, Matrix outputMatrix){
outputMatrix.reset();
outputMatrix.set(mMatrixTouch);
outputMatrix.postScale(0.7f, 0.7f, x, y);
}
/**
* Post-scales by the specified scale factors.
*
@ -229,13 +235,16 @@ public class ViewPortHandler {
public Matrix zoom(float scaleX, float scaleY) {
Matrix save = new Matrix();
save.set(mMatrixTouch);
save.postScale(scaleX, scaleY);
zoom(scaleX,scaleY,save);
return save;
}
public void zoom(float scaleX, float scaleY, Matrix outputMatrix){
outputMatrix.reset();
outputMatrix.set(mMatrixTouch);
outputMatrix.postScale(scaleX, scaleY);
}
/**
* Post-scales by the specified scale factors. x and y is pivot.
*
@ -248,13 +257,16 @@ public class ViewPortHandler {
public Matrix zoom(float scaleX, float scaleY, float x, float y) {
Matrix save = new Matrix();
save.set(mMatrixTouch);
save.postScale(scaleX, scaleY, x, y);
zoom(scaleX,scaleY,x,y,save);
return save;
}
public void zoom(float scaleX, float scaleY, float x, float y, Matrix outputMatrix){
outputMatrix.reset();
outputMatrix.set(mMatrixTouch);
outputMatrix.postScale(scaleX,scaleY,x,y);
}
/**
* Sets the scale factor to the specified values.
*
@ -265,13 +277,16 @@ public class ViewPortHandler {
public Matrix setZoom(float scaleX, float scaleY) {
Matrix save = new Matrix();
save.set(mMatrixTouch);
save.setScale(scaleX, scaleY);
setZoom(scaleX,scaleY,save);
return save;
}
public void setZoom(float scaleX, float scaleY, Matrix outputMatrix){
outputMatrix.reset();
outputMatrix.set(mMatrixTouch);
outputMatrix.setScale(scaleX,scaleY);
}
/**
* Sets the scale factor to the specified values. x and y is pivot.
*
@ -292,24 +307,34 @@ public class ViewPortHandler {
}
protected float[] valsBufferForFitScreen = new float[9];
/**
* Resets all zooming and dragging and makes the chart fit exactly it's
* bounds.
*/
public Matrix fitScreen() {
Matrix save = new Matrix();
fitScreen(save);
return save;
}
/**
* Resets all zooming and dragging and makes the chart fit exactly it's
* bounds. Output Matrix is available for those who wish to cache the object.
*/
public void fitScreen(Matrix outputMatrix){
mMinScaleX = 1f;
mMinScaleY = 1f;
Matrix save = new Matrix();
save.set(mMatrixTouch);
outputMatrix.set(mMatrixTouch);
float[] vals = valsBufferForFitScreen;
for(int i = 0 ; i < 9 ; i++){
vals[i] = 0;
}
save.getValues(vals);
outputMatrix.getValues(vals);
// reset all translations and scaling
vals[Matrix.MTRANS_X] = 0f;
@ -317,13 +342,11 @@ public class ViewPortHandler {
vals[Matrix.MSCALE_X] = 1f;
vals[Matrix.MSCALE_Y] = 1f;
save.setValues(vals);
return save;
outputMatrix.setValues(vals);
}
/**
* Post-translates to the specified points.
* Post-translates to the specified points. Less Performant.
*
* @param transformedPts
* @return
@ -331,16 +354,25 @@ public class ViewPortHandler {
public Matrix translate(final float[] transformedPts) {
Matrix save = new Matrix();
save.set(mMatrixTouch);
final float x = transformedPts[0] - offsetLeft();
final float y = transformedPts[1] - offsetTop();
save.postTranslate(-x, -y);
translate(transformedPts, save);
return save;
}
/**
* Post-translates to the specified points. Output matrix allows for caching objects.
*
* @param transformedPts
* @return
*/
public void translate(final float[] transformedPts, Matrix outputMatrix){
outputMatrix.reset();
outputMatrix.set(mMatrixTouch);
final float x = transformedPts[0] - offsetLeft();
final float y = transformedPts[1] - offsetTop();
outputMatrix.postTranslate(-x, -y);
}
protected Matrix mCenterViewPortMatrixBuffer = new Matrix();
/**
* Centers the viewport around the specified position (x-index and y-value)
* in the chart. Centering the viewport outside the bounds of the chart is
@ -353,7 +385,8 @@ public class ViewPortHandler {
*/
public void centerViewPort(final float[] transformedPts, final View view) {
Matrix save = new Matrix();
Matrix save = mCenterViewPortMatrixBuffer;
save.reset();
save.set(mMatrixTouch);
final float x = transformedPts[0] - offsetLeft();