Design pattern for drawing views in advance to improve responsiveness?

Drawing my views is relatively complex and slow. For higher-memory devices, is there a design pattern to draw views in advance, so that switching between them is more responsive?

Would BufferedBitmaps be an option? Or can layers be used to draw something before a view is put on the top of the view stack?

  • Also, understand that Storage uses the file system, which can slow things down.  The graphics pool will use the file system when something is first loaded (or re-loaded) but it will often be in memory/ 

    Yes, I understand that.

    Regarding memory my approach with BufferedBitmap is not very effective. If I take the AMOLED screen of my Epix2Pro47mm with 416x416 resolution, one pre-rendered screen takes about 169kB, at 8 bits per pixel. Having to store a square bitmap for a round watch-face results in a lot of unused pixels. I may be able to bring the palette down, but I don't think it will be enough, the results would still be unpredictable.

  • A typical screen in my app draws around 10-12 bitmaps, 10-12 text elements, and a few basic shapes like circles and an arc. Drawing text elements in particular seems to be especially time-consuming.

    OK, I guess here I made a bad choice here. The reason why the text rendering is so slow is that I am using vector fonts. When using standard fonts instead, my onUpdate comes down to 38,000us instead of 70,000us.

  • After separating the drawing and precalculation (though both still ran within onUpdate), the total time increased to 80,000 us - only 20,000 us of which was due to precalculation.

    Dear diary: another oddity.

    At least in the simulator/profiler, it seems that drawing vector fonts to a small BufferedBitmap is significantly faster than drawing them directly. After adding this to my testing branch (which now separates drawing and precalculation), the total onUpdate time dropped from about 80,000us to 58,000us. Of that, 37,000us is due to the precalculation step. So if I move that out of onUpdate, I'd be left with just over 20,000us - a big improvement.

    Bit of a surprise, but a welcome one, though I am not sure if this is a real thing, or just happening in the simulator.

    I do not yet have the logic to trigger the precalculation independent from onUpdate, guess I need to do that to see how well it performs on a real device.

  • I have another question for you experts:

    When the app runs, there is an event queue for handling user input, timers and web responses, correct?

    Is there a prioritization, for example does a user input overtake an already queued timer?

    Apart from a timer, is there any other way to insert a task into the queue?

    My refactoring is complete, but especially when the number of views gets too high, the the pre-processing blocks the app and processing of user input is very slow. So, I‘d like to break down the pre-processing in smaller tasks, and inbetween give the app opportunity to process user inputs. 

  • no, no.

    How/when do you enqueue the pre-processing jobs? If you do them all at once, then only enqueue the next one when the previous finished. This way if there's a user input then it can come right after the current job finishes.

  • CIQ is single threaded so it only does one thing at a time.  Another way to add something is requestUpdate, so onUpdate gets called.  I think it's just first in, first out, but it could be a bit smarter for onUpdate, where only the newest one really needs to be called.  I've not verified this.

  • If you do them all at once, then only enqueue the next one when the previous finished. This way if there's a user input then it can come right after the current job finishes.

    That was my thinking as well. I wrote an event queue that processes an event, starts a timer, then processes the next, then starts another timer. I'd post the code, but it is being blocked by the security software of the forum.

  • and if you use clicks and touches then the callbacks are not called before the next timer?

  • Try zipping your project and then adding the zip to the post.  I've done that in the past, especially if things like resources were involved.

  • Yes, as far as I can tell, this way the user inputs are processed before the next timer is called, so all is good.