开发者

Weird performance issue with Galaxy Tab

I am working on a 2d tutorial and was able to test my current tutorial part on a Samsung Galaxy Tab.

The tutorial simply moves the default icon randomly over the screen. With a tap I create a new moving icon. Everything works fine (constantly 60fps) on the Galaxy as long as I have 25 elements or less on the screen.

With the 26th element the frame rate drops to 25fps.

When I change the size/dimension of the image to a much bigger one, I reach less than 25fps before the 26th element. Thats ok. But at some not really reproducible number of elements the frame drops from (mostly more than) 10fps to 1fps.

On my Nexus One I can add 150 elements and still have 50fps.

What I have done: I changed the bitmap variable to a static one, so not every element has his own image but all use the same. That removed the behavior, but I doubt this solution is a good one. The magic number of 25 would suggest that I can use only 25 different images in that way.

Does someone have any idea what can cause this behavior? Is it a bug in the modified android version of Samsung?

My sample eclipse project is available. I would appreciate if some Samsung owner would check their performance with the sample.

edit

A col开发者_运维问答league found a solution. He changed the way the bitmap is loaded from

mBitmap = BitmapFactory.decodeResource(res, R.drawable.icon);

to

mBitmap = BitmapFactory.decodeStream(new BufferedInputStream(res.openRawResource(R.drawable.icon)));

But we still don't really get it why it works this way...


Well, I've been looking on your project and everything seems to be fine, but I have one idea about what's causing you the frame rate drop.

You're allocating objects during runtime. If you don't do that, it will make you create all objects at start, and therefore you should notice a significant drop directly (if my solution doesn't solve your problem).

That said; I'm not sure whether an object pool will solve your problem, but you can try. Initialize your objects in a constructor and instead of making this call in onTouchEvent():

new Element(getResources(), (int) event.getX(), (int) event.getY())

You should have something like mElement.add(objectPool.allocate()), where the object pool finds an unused object in the pool. Also, we should have a specified amount of objects in that object pool and from there you can check if it is the allocating that is causing this error or if it is something else.

With the 26th element the frame rate drops to 25fps.

When (or if) you implements this, you should see the frame rate drop directly (if this doesn't solve your problem though), since the object pool will make you allocating a fixed amount (e.g. maybe 100 elements?) at start (but you're not using them visually).

Also, I have used the memory pool pattern (object pool) in one of my sample applications for Android. In that sample; I add a line to the Canvas on an onTouchEvent() using an object pool (without allocating during runtime). In that source code you can easily change the total amounts of objects and check it out and try it yourself. Write a comment if you want to look at my sample application (and source code) and I will gladly share it since it's not public yet. My comments are in Swedish, but I think you should be able to understand, since the variables and methods are in English. :)

Side note: You wrote that you've tried (and even success) with removing the behaviour by making your Bitmap static. As it is right now, your elements have different instances of a Bitmap, which will make you allocate a new Bitmap everytime you're constructing a new object. That means that every object is pointing to a different Bitmap when they are using the same resource. static is a fully valid solution (although a magic number of 25 seems wierd).

This Bitmap case can be compared to the OpenGL system. If you have 20 objects which all should use the same resource, there are two possible solutions: They can point to the same VRAM texture or either they can point to a different VRAM texture (like your case when you're not using static), but still same resource.

EDIT:

Here is my sample application for Android that demonstrates the Memory Pool.

Regarding your solution with BitmapFactory, that probably depends on how that class works. I'm not sure, but I think that one of the decode...() methods generates a new Bitmap even if it is the same resource. It can be the case that new BufferedInputStream(res.openRawResource(R.drawable.icon)) is reusing the BufferedInputStream from memory, although, that is a big guess.

What you should do (in that case) is to decode a resource and store a reference from it in the Panel class and pass that reference into the new Element(bitmapReference, ...) instead. In that way, you're only allocating it once and every element is pointing to the same Bitmap in memory.


I have tried your code on HTC Desire HD and the frame rate drops down to unusable after added 20th image using Android 2.2 target. When I exported the same code as android version 2.1 then it worked fine and could handle over 200 instances! I suspect that it is to do with creating instances of your GraphicObject class on 2.2, but not quite sure...


I believe i can shed some light on this problem.

At least on my Galaxy S, Gingerbread 2.3.5 the first code loads my test.png into Bitmap with Bitmap.Config = ARGB_8888, while the second code loads with Bitmap.Config = RGB565. The strange thing is, while Gingerbread by default supposed to create 32bit surface, the RGB565 'renders' (I profiled and compared native call to drawBitmap) much faster.

Hence, The second idea, more appropriate for the your example as a whole, is that ARGB888 Bitmap does have alpha, so in that case rendering overlapping images of 25+ sprites could create some bottleneck in alpha calculation algorithm, while RGB565 image would be fine and fast.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜