Improving Graphical Performance
|Top Previous Next|
Nobody likes sluggish products, and the way you work with your display can greatly influence perceived performance of your product. We say "perceived" because very often this has nothing to do with the actual speed at which your device completes required operations.
Group display-related operations together
The most important aspect of your application's performance (related to the display) is how fast the data on the display appears to have changed. Interestingly, what matters most is not the total time it takes to prepare and show the new data, but the "togetherness" at which all new displayed items pop up on the screen.
Let's illustrate this point. Here are two code examples that do the same and take roughly the same time to execute. We calculate and print two values. In the first example, we calculate and print value 1, then calculate and print value 2:
In the second example we calculate values 1 and 2 first, then print them together:
Testing both examples shows that the perceived performance of the second code snippet is much better, while, in fact, the total working time of the processor was roughly the same. Why is there a difference? Because the output of the two values in the second example was spaced closer!
Bottom line: keep all display output as close together as possible. Pre-calculate everything first, then display all your items "at once".
Use display locking
No matter how hard you try to group all display-related output together, executing lcd. object's methods one after another may still take considerable time. Perceived performance can be improved on displays that allow you to "lock" display picture, change display data, then unlock the display again. With this approach, the user will see all changes appear instantly! Not all displays are suitable for this. Typically, this works well for TFT panels which continue to display the image for several seconds after the "refresh" was disabled. Other display types are not suitable for locking. We have provided locking-related info for each supported controller/panel.
Display-related code is often nested, with one procedure calling another, and so on. If you are using display locking, you should ideally place locks/unlocks in each related routine. A complication arises with regards to when to unlock the display. For example, supposing you have two subs: lcd_sub1 and lcd_sub2:
Lcd_sub2 gets executed when invoked directly by the main code, and also when the lcd_sub1 is called. In the second case, the display should not be unlocked at the end of lcd_sub2 because the output is to be continued in lcd_sub1! And you know what? The display won't be unlocked because with the lcd object it is possible to nest locks/unlocks! In the following example, we do three consecutive locks and the display is locked right on the first one. We then do three consecutive unlocks, and the display is not unlocked until after the third one is executed:
The lock/unlock mechanism maintains a counter, which can actually be read through the lcd.lockcount R/O property. Each invocation of lcd.lock increments the counter by 1, each lcd.unlock decrements it by 1. The display is only unlocked when the counter is at 0, and locked when the counter is >0. This allows you to nest display-related procedures and safely have lock/unlock in each one of them!