In the course of developing an Android application, I'm finding a need
to draw several unfilled concentric circles centered on an arbitrary
point, enough that some of them are only partly visible on the
display. However, this does not appear to work with hardware
acceleration. My test rig is a stock Samsung Galaxy Tab 10.1 running
Android 3.2.

The following code comes from a test subclass of View I wrote to
isolate the issue:

private Paint paint = new Paint();

private int count = 0;

private static final int[] COLORS = { 0xffff0000, 0xff00ff00,
0xff0000ff, 0xffff00ff };

public TestCircles(Context context) {
    super(context);
    paint.setStrokeWidth(1.0f);
    paint.setStyle(Paint.Style.STROKE);
}

public TestCircles(Context context, AttributeSet attributes) {
    super(context, attributes);
    paint.setStrokeWidth(1.0f);
    paint.setStyle(Paint.Style.STROKE);
}

public boolean onTouchEvent(MotionEvent e) {
    if (e.getAction() == MotionEvent.ACTION_DOWN)
        invalidate();
    return true;
}

protected void onDraw(Canvas canvas) {

    // Pick the color to use, cycling through the colors list
repeatedly, so that we can
    // see the different redraws.
    paint.setColor(COLORS[count++]);
    count %= COLORS.length;

    // Set up the parameters for the circles; they will be centered at
the center of the
    // canvas and have a maximum radius equal to the distance between
a canvas corner
    // point and its center.
    final float x = canvas.getWidth() / 2f;
    final float y = canvas.getHeight() / 2f;
    final float maxRadius = (float) Math.sqrt((x * x) + (y * y));

    // Paint the rings until the rings are too large to see.
    for (float radius = 20; radius < maxRadius;
            radius += 20)
        canvas.drawCircle(x, y, radius, paint);
}

I am running TestCircles as the only View in an Activity, laying it
out to fill the available width and height (i.e. it is nearly full-
screen). I can tap on the display (triggering redraws) only a few
times before the redraws no longer occur (i.e. the circles' color
doesn't change). Actually, the onDraw() code is still running in
response to each tap -- as proven with diagnostic messages -- but
nothing changes onscreen.

When onDraw() first starts to fail to redraw, the debug log includes
the following entry, once for every call to onDraw():

    E/OpenGLRenderer(21867): OpenGLRenderer is out of memory!

If I turn off hardware acceleration in the manifest, these problems go
away -- not surprising since clearly OpenGL is having problems -- and
actually it is a good deal faster than the few times it actually works
under hardware acceleration.

My questions are:

First, am I misusing Canvas, or is this a bug, or both? Is Android
allocating large bitmaps under the hood to draw these circles? It
doesn't seem like this should be this challenging to OpenGL, but I'm
new to hardware accelerated app development.

Second, what's a good alternative way to draw large unfilled circles
that have portions extending out of the clipping region of the Canvas?
Losing hardware acceleration is not an option.

Thanks in advance...

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to