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:

 

 

Dim dw1,dw2 As dword

...

'Note so good! The user will see a noticeable delay between the first and the second print.

lcd.print(str(dw1*100/200),0,0)

lcd.print(str(dw2*100/200),0,10)

 

 

In the second example we calculate values 1 and 2 first, then print them together:

 

 

Dim dw1,dw2 As dword

Dim s1,s2 As String

...

'Much better. The user will have a feeling that both values were calculated and printed instantly!

s1=str(dw1*100/200)

s2=str(dw2*100/200)

lcd.print(s1,0,0)

lcd.print(s2,0,10)

 

 

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.

The display is locked/unlocked using the Lcd.lock and lcd.unlock methods. You can place lcd.lock before the block of code that changes display data, and put lcd.unlock at the end of this code block:

 

 

...

s1=str(dw1*100/200)

s2=str(dw2*100/200)

lcd.lock 'lock the display

lcd.print(s1,0,0)

lcd.print(s2,0,10)

lcd.unlock 'unlock the display

...

 

 

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:

 

 

'some main routine that invokes lcd_sub1 and lcd_sub2

....

....

lcd_sub1

...

...

lcd_sub2

...

End Sub

 

'-----------------------------------------

Sub lcd_sub1 'calls sub2 too

lcd.lock

...

lcd_sub2

...

lcd.unlock

End Sub

 

'-----------------------------------------

Sub lcd_sub2 'called by sub1

lcd.lock

...

lcd.unlock

End Sub

 

 

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:

 

 

...

lcd.lock 'lcd.lockcount=1, display is now locked

lcd.lock 'lcd.lockcount=2

lcd.lock 'lcd.lockcount=3

lcd.unlock 'lcd.lockcount=2

lcd.unlock 'lcd.lockcount=1

lcd.unlock 'lcd.lockcount=0, display is now unlocked

...

 

 

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!