The Artima Developer Community
Sponsored Link

Agile Buzz Forum
Display, VisualWorks and Flicker - Part 2

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
James Robertson

Posts: 29924
Nickname: jarober61
Registered: Jun, 2003

David Buck, Smalltalker at large
Display, VisualWorks and Flicker - Part 2 Posted: Oct 5, 2003 5:24 PM
Reply to this message Reply

This post originated from an RSS feed registered with Agile Buzz by James Robertson.
Original Post: Display, VisualWorks and Flicker - Part 2
Feed Title: Pollock
Feed URL: http://www.cincomsmalltalk.com/rssBlog/pollock-rss.xml
Feed Description: Pollock - the next VW GUI
Latest Agile Buzz Posts
Latest Agile Buzz Posts by James Robertson
Latest Posts From Pollock

Advertisement
Now that we have the basis for further details, we can look at the Wrapper mechanisms for displaying things. There are, in face, three ways in which the VisualWorks GUI framework gets things displayed. As is my wont, I will name these to make it easier for us to refer to them.

Invalidate Now: In this method, an area of the window is asked to display itself. Here's how it works. When an Invalidate Now is sent to a window, it is also sent a rectangle which describes the area of the window that needs to be redrawn. Typically, this is just the area of a widget that wants to be redrawn. The window then gets a GraphicsContext, sets that GraphicsContext clipping rectangle to be the same as the rectangle passed in, and then, asks each sub-component in that window to display itself on that GraphicsContext.

Now here is what Wrapper in ALL of it's components does. EVERY component that is in that window, no matter where in that window, dutifully paints itself on the GraphicsContext. Let's look at the implication of this statement. Suppose that we had 100 buttons, laid out in a 10 x 10 matrix on the window. Now let's suppose that the forth one down, third one over, asked (maybe because it was pressed and needed to temporarily show it self in its pressed state) "Invalidate Now" for itself. All the other 99 buttons would paint on the GraphicsContext. As stated above, the GraphicsContext at this time would have a clipping rectangle that restricted actual display to the area of the 33rd button. However, that does NOT mean that all of the other buttons wouldn't go through the (useless) motions of having ALL of the buttons execute all of their display code.

Take a moment and think about a standard Windows 9x button. The button is made up of the following paint commands:
  1. Paint a filled rectangle, covering the whole area of the button either Pressed or Unpressed button background color (depending on the current pressed state)
  2. Paint a line along the top edge (1 pixel high) button highlight color
  3. Paint a line along the second row of pixels from the top button border color
  4. Paint a line along the left edge (1 pixel wide) button highlight color
  5. Paint a line along the second column of pixels from the left edge (1 pixel wide) button border color
  6. Paint a line along the bottom edge (1 pixel high) black
  7. Paint a line along the second row of pixels up from the bottom edge (1 pixel high) button shadow color
  8. Paint a line along the right edge (1 pixel wide)
  9. Paint a line along the second column of pixels in from the right edge (1 pixel wide) button shadow color
  10. If the button has focus, paint an rectangle 4 pixels in from the edges (1 pixel wide) button "focus" color (we call it traversal highlight)
  11. Paint the text for the button's label at "the right place" in button foreground color.
Most of the above discreet paints consists of two Smalltalk statements: One to set the color, one to do the draw. Of course, there is much more code than that. For instance, small bits of code to figure out where each line is, where the text should be, and so on and so on. Lots of details... just be glad you don't have to write it.

Bottom line, that code executes 100 times, and only 1 of these times actually does it actually have an effect on what you see.

Pollock has seen this as being a terrible waste of execution time. In Pollock, each pane looks to see if it's current bounds intersects the GraphicsContexts clipping rectangle. If it does not, it does not do any painting. So, Pollock is a bit smarter, in that the actual paint code will only execute once for our scenario here.

Damage: This method could also be known as "Invalidate Later." What happens here is that, someone has told the window that a rectangle on the window needs to be repainted but, "Not Now." There are two places these Not Now rectangles come from. One is from the OS itself. When ever an area of a window is first occluded and then re-exposed, the OS will kindly tell the window the rectangle (or rectangles) that have just be re-exposed. The other place these come from is from within VisualWorks itself. Somewhere either a widget or another actor will ask that a widget be invalidated.

Wait a second, you say, didn't you talk about invalidate in the Invalidate Now method? Yes, but... What I didn't say is that all invalidates come in to the invalidate processing machinery with a flag, that flag saying "Do Me Now" or "Do Me Later." If the flag says "Do Me Now", then the Invalidate Now action occurs. If it says "Do Me Later", no actual displaying is asked to be performed. Instead, the rectangle (which is also always passed in) is put into a collection with any other "Not Now" rectangles. These captured rectangles are held on to until one of two things occur. Either a direct request to "display pending damage" or an "Invalidate Now."

If the request was an "Invalidate Now", the system first performs the following "display pending damage" BEFORE it executes the Invalidate Now body. The display pending damage works like this: First, it goes through all of the damage rectangles, and collects any that intersect in any way into a new rectangle that is the combined area of both. It does this until it has either one rectangle, or a collection of non intersecting rectangles. Then it in effect calls the "Now" part of the Invalidate Now behavior for each of these rectangles.

Here is a fact you should be aware of. In Wrapper, about half of invalidates come into the invalidation system with the "Do Me Now" flag turned OFF! In Pollock, its about 75%.

Direct Write: This method is where a widget, instead of sending invalidate me in some way or another, it simply gets a GraphicsContext and starts writing to it, directly.

This happens a lot. For instance, when you type in a single character, or insert text into a field, instead of redisplaying the whole text, it figures out what area has changed, and only displays that. Sometimes, it forces almost all of the field to be redisplayed, sometimes not, depending on effect of the action. Another example is when you select text and no scrolling of the text occurs because of your selection. Only the area being selected is redrawn. These of course make a lot of sense. No reason to go through redrawing a whole field if only a small part of it changes visually.

However, don't assume that this is the only time this is done. Sometimes the developers of Wrapper (and in myself in Pollock) got lazy, and instead of saying Invalidate a specific rectangle now, they just decided, screw that, I'll just display the change I want right here right now.

None of the above is a problem per se. However, because of the needs of various widgets to do a lot of complex drawing, and other assumptions that are not valid when that painting occurs, the bottom line is that the above system, stated as it is above, and the above is the default, can cause a lot of flicker.

In Part 3, we'll layout why the flicker occurs, both some reasons you would expect, and some you wouldn't. Then, we'll get on to how Pollock plans to deal with it.

And So It Goes
Sames

Read: Display, VisualWorks and Flicker - Part 2

Topic: Reflections when modifying a complex program Previous Topic   Next Topic Topic: Request Filtering

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use