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

Reply via email to