Hi Andreas, Sorry to jump in late, but I thought I'd share my experiences with non- opengl on Android.
I have a game "engine" which uses both open gl and the canvas system depending on the device capabilities (some devices, like HTC Tattoo have software implementations of opengl which is actually slower than canvas). I get reasonable performance from the canvas api, but the important thing is that the bottle-neck has always been draw speed and nothing else. I pretty much followed the replica island approach whereby I have two threads, one which just draws and the other where all the game calcs are done. My game thread routinely outperforms my render thread, but I am drawing quite a lot so this may not be everyone's experience. I'd say you do have a slight architectural flaw in that (it appears) that your game logic is being computed in the same thread as the rendering. This means that the render thread has to wait each frame for the game to update state. It's much better to separate these two. Have your game logic updated in a separate thread, then just notify the render thread when it's time to draw (you can do this by sending a message to your surface view using a Handler and then invalidating the canvas). Basically what I do is this: I have a separation of game objects, and "renderable" objects. A game object is the real representation of the in-game element (eg the player). The renderable object is simple a set of x,y coords, plus scale, rotation etc and a reference to the image that represents the sprite (I have some more logic to include sprite animations etc, but the basic concept is the same). Hence my renderables are "dumb". They don't know what they are, they just know how to be drawn. My game objects contain all the important logic information (eg player health etc). This is how I cater for both Canvas and OpenGL. I have CanvasRenderable objects and OpenGLRenderable objects which both extend a common base class (... you guessed it.. Renderable). This base class pretty much has just one method... draw(). (actually it sends in a reference to the graphics context... so either Canvas or GL10, but you get the idea) When the render thread is drawing the renderables, the game thread is processing the next "step" in the game. Once the game thread has completed its step, it waits for the render thread to complete (I implemented a simple mutex sort of like the java ReadWriteLock, but one that doesn't allocate a bunch of objects like the ReadWriteLock does!). Once the render thread has completed, I send all the updated coordinates, rotations etc to the renderable objects from the game object counterparts. While I am doing this, I prevent the render thread from rendering the next frame (using the same mutex) so it isn't rendering objects in a half-moved state. Then the game thread is ready to process its next step, and it uses the time taken to process the last step (including the time spent waiting for the render thread) as the input into the calculations. The end result is that the render thread is just doing one thing.. rendering... as fast as it can. All the actual logic is separated into the Game Thread. The only delay in each frame is the time it takes to set all the coordinates etc on the renderables.. which is usually pretty fast. The third thread is just the Activity which handles the user input etc. This will typically only affect objects in the Game Thread (eg increase speed of player etc) As far as GC calls go, I have not been able to eliminate them completely (there still seem to be allocations buried in the Android api which I can't seem to get rid of) but they are infrequent enough that it's not really an issue. I just used the Allocation Tracking to locate any dodgy allocations and re-code them out. I'm currently not rendering any Strings however (not during gameplay anyway), but you could also get around this by not writing text as such, but by simply drawing each character as an image. So you have a small image for each alpha-numeric character you need, then maintain a fixed size array of values representing the "String" you need to draw. Then you just draw a sequence of images. Of course you would abstract this so it makes your life easier (eg create a "renderable" which takes a numeric value and knows how to draw it as a sequence of images at an x,y position). I assume you have already done so, but if not I strongly recommend you watch the YouTube video of Chris Pruett explaining his game architecture. Made a lot of sense to me. http://www.youtube.com/watch?v=U4Bk5rmIpic Not sure if I've really been any help here, but if you have any questions I'd be happy to share whatever I have learnt (so far). Cheers, Jason. On Sep 15, 6:04 pm, Andreas <[email protected]> wrote: > Hi miguel, > thanks for the response. > > Afaik. Every example game written by the google guys has a inner > thread class in the gameview. But i think only for sharing variables > of the gameview. Not quite sure if there where any other advantages > gc wise. > > Normally locks a more a timesink and slowing down the thread, or is > there a case where it can speed up performance. And from the normal > java world. Locks like synchronized where needed while multithreading. > Do you have more threads working on some objects? > > Currently i have 1 thread running for the surface view. This thread > has a instance variabel gamedata where everything is happening. All > lists of game objects are located in the gamedata object. Maybe this > is a archtectural flaw ? > > The game view implements the touchlistener an delegates the inputs to > the thread via thread save queue. The other direction, like the thread > send a value to the score textview happens via messagehandler who > delegates the msg to the referenced views. > > I think i rewrite a test project focussing on testing how i get rid of > the hiccups. > > On 15 Sep., 00:09, Miguel Morales <[email protected]> wrote: > > > > > > How are you avoiding String Concatenation ? TextFields as a Example > > > only take Strings > > > I don't really use this myself because I don't really strings in inner > > loops. > > First, you want to make those time elements draw/update as least as > > possible. > > If not, you can use a string > > buffer:http://developer.android.com/reference/java/lang/StringBuilder.html > > > A) Don't know, ddms works great for me. Try using it outside of > > eclipse, it works better by itself. > > b) I don't think there is a way, try playing with ddms. (I believe > > outside of eclipse it has more features) > > c) Depending on how you communicate with your inner/display thread, I > > use locks for speed. > > > On Tue, Sep 14, 2010 at 2:39 PM, Andreas <[email protected]> > > wrote: > > > How are you avoiding String Concatenation ? TextFields as a Example > > > only take Strings > > > And if you have a Score, or Time Element that Shows Some Numbers i > > > wasn't able to get around creating a String implicitly. > > > > Currently i'am testing on my Motorola Milestone. On the Emulator it > > > even runs slower with constant hiccups. > > > > Some other Problem while researching the hiccups: > > > a) > > > Currenty the Method Profiling in Eclipse isnt' working because of a > > > error > > > "Unable to open trace file 'sdcard/com.an........trace' : Permission > > > Denied. > > > Kind of Strange because a added <uses-permission > > > android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> already in > > > the Manifest. > > > > b) Is there any way that logcat shows which objects where recycled ? > > > Currently it only says GC freed xyz > > > Simply because the Allocation View don't show me Thread Objects that > > > may cause the GC to run so often. > > > > c) Is there any big disadvantage if the GameThread is a "outer > > > Thread"..not like in all the examples (there it.s a inner class) > > > > thanks 4 feedback > > > > On 14 Sep., 22:45, Miguel Morales <[email protected]> wrote: > > >> Are you using the emulator or a hardware device for testing? I'm sure > > >> there's gotta be something that's allocating in your code. In my > > >> personal experience, I've gotten the GC down to once a minute at the > > >> worst. A lot of the time you can't fully get rid of GC hiccups > > >> because of background applications that allocate objects. > > > >> Make sure you're not appending any string, check any other background > > >> code that's running (like your logic loop). You have to make sure > > >> there's no allocations throughout any long running or looping code. > > > >> I'm fairly sure the canvas onDraw method doesn't allocate anything by > > >> itself, and you can get some decent performance out of it without > > >> going to openGL. > > > >> I'm sure you've seen this but just in > > >> case:http://code.google.com/events/io/2009/sessions/WritingRealTimeGamesAn... > > >> It outlines some common pitfalls. > > > >> On Tue, Sep 14, 2010 at 1:02 PM, Andreas <[email protected]> > > >> wrote: > > >> > to 1) > > > >> > Did that already. I ruled out everything that was creatinglike shadow > > >> > Copies or String Concat. I re-implement my own FastList instead of any > > >> > ArrayList oder Hashmap. > > >> > To there is nearly nothing that is created intentionally. But the GC > > >> > is anyway running every couple of seconds. Sometimes only 50 ms > > >> > somtimes 500 ms. The thing > > >> > might be, hat you can't tell the GC that he should hold on for some > > >> > time. It's not in my hands, and since everything in 2d drawing and > > >> > standard Android Libs is in the > > >> > GC domain and will be interrupt the game for some ms. > > > >> > 2) i think i have about max 100-150 Objects moving around in my > > >> > screen. + the "not moving" static objects. I tested it with 200 > > >> > Objects but the only flaw i saw was the GC hiccups > > >> > issue. > > > >> > 3)opengl has a hard learning curve. And since i develop Java for about > > >> > 10 Years now i thought i could handle the graphic stuff via the > > >> > canvas / draw architecture. Since this might be a KO Criteria I'm > > >> > kind of afraid to rewrite my game to use the andengine. > > >> > I've already read about it...and saw some examples...but I'm not sure > > >> > if how long it will take to get me going with this engine. I would > > >> > love to see a engine i could "plug in my app". I design my app that > > >> > way, that i have 2 major methods called in my game loop > > > >> > upateGameData() > > >> > and > > >> > drawGameData() > > > >> > in the draw Method i iterate over all different gameObect Lists...like > > > >> > drawMonsters(c) > > >> > drawMissels(c) > > >> > drawStaticBlabla(c). > > > >> > UpdateGameData does the Math (e.g. positioning for animations )and is > > >> > kind of unrelated with drawing besides some things the Update Methods > > >> > have to know....like Resolution / Borders . > > > >> > everything that can be draw on a canvas has to implement a update(c) > > >> > method where the object draws itself. Would be cool to replace the > > >> > "c" for canvas with a OPenGL maybe Andengine Surface but i don't think > > >> > that's gonna be the case. Would be to nice ^^ > > > >> > On 14 Sep., 15:39, Justin Giles <[email protected]> wrote: > > >> >> Just a few moderately uninformed comments/questions... > > > >> >> 1) Use DDMS and MAT to try to nail down any possible memory issues > > >> >> that you > > >> >> might be overlooking. > > > >> >> 2) Canvas 2D does have significant limitations compared to OpenGL > > >> >> when it > > >> >> comes to a large number of sprites on the screen at once. Is this a > > >> >> possible issue for you? > > > >> >> 3) You might check out Andenginehttp://www.andengine.org(notaffiliated > > >> >> with them). It is a 2D opengl framework that is a whole heck of a lot > > >> >> easier to get a 2D game up and running than using raw openGL (in my > > >> >> opinion). > > > >> >> Justin > > > >> >> On Tue, Sep 14, 2010 at 7:44 AM, Andreas > > >> >> <[email protected]>wrote: > > > >> >> > Hi Folks, > > > >> >> > im currently playing around with a Game that architecture is > > >> >> > basically > > >> >> > like the example 2d Games like JetBoy / LunarLander and so on. But > > >> >> > as > > >> >> > things now running (and animating continuously) they have kind of > > >> >> > "hiccups" when the GC is running. I have done all i can to allocate > > >> >> > as > > >> >> > much Objects in front. There is nearly nothing that is created "new" > > >> >> > besindes some Strings that are used to set the Score and so on. > > >> >> > (TextView doesn't take int's =( - > > > >> >> > So do you have similar Problems that the GC is "lagging" your 2s > > >> >> > game ? any solutions ? > > > >> >> > Thanks for suggestions > > > >> >> > -- > > >> >> > You received this message because you are subscribed to the Google > > >> >> > Groups "Android Developers" group. > > >> >> > To post to this group, send email to > > >> >> > [email protected] > > >> >> > To unsubscribe from this group, send email to > > >> >> > [email protected]<android-developers%2Bunsubs > > >> >> > [email protected]> > > >> >> > For more options, visit this group at > > >> >> >http://groups.google.com/group/android-developers?hl=en > > > >> > -- > > >> > You received this message because you are subscribed to the Google > > >> > Groups "Android Developers" group. > > >> > To post to this group, send email to > > >> > [email protected] > > >> > To unsubscribe from this group, send email to > > >> > [email protected] > > >> > For more options, visit this group at > > >> >http://groups.google.com/group/android-developers?hl=en > > > >> -- > > >> ~ Jeremiah:9:23-24 > > >> Android 2D > > >> MMORPG:http://developingthedream.blogspot.com/,http://diastrofunk.com,http:/... > > > > -- > > > You received this message because you are subscribed to the Google > > > Groups "Android Developers" group. > > > To post to this group, send email to [email protected] > > > To unsubscribe from this group, send email to > > > [email protected] > > > For more options, visit this group at > > >http://groups.google.com/group/android-developers?hl=en > > > -- > > ~ Jeremiah:9:23-24 > > Android 2D > > MMORPG:http://developingthedream.blogspot.com/,http://diastrofunk.com,http:/... -- You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/android-developers?hl=en

