0

Background information: I am portioning the prefuse framework to android (named from me as AndroidPrefuse). I have done most of the work and it works at least for one visualization (a scatterplot). I have noticed that the android version for "high" amount of data (over 10000 items) is very slow.

I have noticed prefuse (in desktop version) does use BufferedImage to draw. I assume it is to gain performance. Here is the code:

protected BufferedImage m_offscreen;
...
public void paintComponent(Graphics g) {
    if (m_offscreen == null) {
        m_offscreen = getNewOffscreenBuffer(getWidth(), getHeight());
    }
    Graphics2D g2D = (Graphics2D)g;
    Graphics2D buf_g2D = (Graphics2D) m_offscreen.getGraphics();

    paintDisplay(buf_g2D, getSize());
    paintBufferToScreen(g2D);
...
protected BufferedImage getNewOffscreenBuffer(int width, int height) {
    BufferedImage img = null;
    if ( !GraphicsEnvironment.isHeadless() ) {
        try {
            img = (BufferedImage)createImage(width, height);
        } catch ( Exception e ) {
            img = null;
        }
    }
    if ( img == null ) {
        return new BufferedImage(width, height,
                                 BufferedImage.TYPE_INT_RGB);
    }
    return img;
}

At first i did skip this kind of "buffering" at AndroidPrefuse. After I noticed the performance issues I tried this:

protected void onDraw(Canvas canvas)
{
...
    int width = getWidth();
    int height = getHeight();       
    if (m_offscreen == null)
    {
         bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
         m_offscreen = new Canvas(bitmap);
    }
    paintDisplay(m_offscreen);
    canvas.drawBitmap(bitmap, 0, 0, null);
...

But the result was the same. I'm new to android, there fore the questions might be trivial:

First question: Have I done it right i.e. the same as prefuse original did?

I have the feeling that the code above is the same as "non buffering":

protected void onDraw(Canvas canvas)
{
...
  paintDisplay(canvas);
...

Am I right? If yes, is there a way to increase the speed of my AndroidPrefuse the same way the original prefuse did (with BufferedImage)?

The method "paintDisplay" renders all the items. For 10000 items it needs 1100ms (on Samsung Galaxy S5). It doesn't look much, but when I pan and zoom, the application is not smooth anymore, as it is with 100 items.

For the record: I also implemented the View as a SurfaceView and did the processing of the method "paintDisplay" in a separate Thread. But it did not increased the speed.

If using Bitmap to increase the performance is not a good solution, does anybody has a idea how to improve the performance?

dritan
  • 882
  • 2
  • 8
  • 22
  • Your `paintDisplay()` function is software-rendering to an offscreen bitmap, so using a SurfaceView isn't going to help. You need to render fewer items, render individual items more quickly, or some combination of the two. Do you see a noticeable improvement if you make the Bitmap smaller (e.g. cut the width and height in half)? – fadden Mar 05 '15 at 18:16
  • @fadden render fewer items is for the moment not an option for me. Because all of the items should be shown on the screen. I did not understood your proposition about making the Bitmap smaller. If I do so, what would be the result? A smaller graphic on the screen? I'm afraid the only option left for me is to render individual items more quickly. But for the moment, I do not know how to. Do you have any general suggestions? :-) – dritan Mar 05 '15 at 19:33
  • If rendering at a lower resolution helps, you can render at (say) half size and let the hardware scale it up. See https://www.youtube.com/watch?v=qpRaD-ij2xc for a demo. If the bulk of the time is in computation and processing, rather than consumed by pixel fill rate, then this approach isn't going to help. – fadden Mar 05 '15 at 23:10
  • @fadden do you have an example to show me how can I do it? – dritan Mar 06 '15 at 10:08
  • I would suggest you halve the dimensions passed to the Bitmap constructor and compare the timing before and after. If that shows an improvement, switch to a SurfaceView and see the "hardware scaler exerciser" activity in Grafika (https://github.com/google/grafika). – fadden Mar 06 '15 at 16:47
  • I've halved the dimensions. But the performance of application was not significantly increased (approximately 5%). I've made some more measurements and found out that the pure rendering of the items (e.g. canvas.drawPath() or canvas.drawOval etc) 560ms needed. I.e. 51%. The other 49% were made by prefuse. I have to look whether I can do some optimizations on this part. – dritan Mar 08 '15 at 09:56

0 Answers0