Hi Stephan, Stephan Assmus wrote: > May I add that I have tried to understand the Layer tree traversal > several times now, but I just don't get it. I also read over it several > times in Adis new clipping code, which is a lot cleaner, because it > doesn't have so much other stuff in it. for (Layer *lay = VirtualBottomChild(); lay; lay = VirtualUpperSibling()) { ... } Why I do this? Because of WinBorders. Layers are a linked list, WinBorders are not. The list of WinBorders is kept per Workspace and changes frequently. When it changes, I query the active workspace which gives me the WinBorder list. WinBorder's VirtualXXXYYY() use an index to iterate through the array, Layer's cache the "current layer" in the linked list. > What is the adventage of doing it like it is done=3F Compared to using > BList or something similar as a container for each Layers children=3F To be honest, I didn't think of doing this in other way. That's how it's done in BView so that's how DW and me did it over here. Maybe it could be better using a BList as insertions and deletion of elements is rare compared to tree traversal operations... > That aside, the clipping calculation still looks like it might have to > recalculate too much during each run. Of which clipping code are you talking about? The new one? If yes, I can assure you that's not the case, with an expection(in the next paragraph). I have tested the new code to be sure it won't calculate anything that's not needed. Ever since you started looking at clipping code you asked me what fFull, fFullVisible and fVisible are for. I have explained that once, and I will explain again with the new clipping code in mind. * fFull - is not used anymore. This was used to cache the area a layer wanted for itself, including user constrain regions. That was nice as it was not the case to rebuild the region a layer wanted every time a clipping operation took place. Think about WinBorders that have decorators with rounded corners - this could avoided quite a few CPU cycles. This member in gone in the new clipping code. It is calculated every time it is needed - done for simplicity and less memory consuption. * fFullVisible - This holds the visible are of a layer + the visible areas of ALL descendants. This region is not necessarily a must, but avoids a lot of CPU cycles. For example, when moving a window, we need the region that windows occupied on screen, which is exactly what this region contains. If it not were for this region, with every move of the window(each step), this region must be rebuilt. You'll say: cache it. Yes, that's a solution, but I'm not convinced it's an easy and clean one. This member can be removed and save some memory at the expense of quite a few CPU cycles. I wanted to talk about this with you guys... do you think we should offer a runtime option to have this active or inactive? * fVisible - is the actual visible region of a layer without the visible regions of its descendants. > Here is some pseudo code which I > have been rolling in my head (just typing it now, so please excuse > obvious erros): > > void > Layer::RebuildLocalClipping() > { > fLocalClippingRegion.Set(Bounds()); > for (int32 i =3D 0; Layer* layer =3D ChildAt(i); i++) { > fLocalClippingRegion.Exclude(layer->Frame()); > } > fScreenClippingRegionValid =3D false; > } > > const BRegion& > Layer::ScreenClipping(bool forceRebuild) > { > if (forceRebuild || !fScreenClippingRegionValid) { > fScreenClippingRegion =3D ConvertToTop(fLocalClippingRegion); > fScreenClippingRegion.IntersectWith(Window()->ScreenClipping()); > fScreenClippingRegionValid =3D true; > } > return fScreenClippingRegion; > } I know it sounds easy at a first thought, but there are quite a few variables involved. > [This code takes the fact into account, that sibbling views don't clip > each other. In BeOS, you just have to make sure that views on the same > level don't overlap, or both are alowed to draw in the same area.] I the code I wrote only the last added view will get the common region if they overlap. I saw this behavior on BeOS some time ago when I did some tests, and IMO that is the right way to go. (AFAI'm concerned, it's the same behavior as with windows) > Note that the local Layer clipping only ever changes if the Layer > itself is resized or if there is a change with its children (add/remove > /show/hide/move/resize). When for example moving windows, this does not > happen at all! In the new clipping code visible regions are only offset-ed when moving windows. Not a CPU intensive task. > What this code hides is the fact that the "dirty" region > needs to be tracked as well during any changes. But I don't see any > problems there. In any case, isn't this just much more straight forward > as a basis for the real algorithm? I wouldn't say... It's the same thing. You keep visible regions local, I keep them in screen coords. At a given time we both have to calculate something. When moving a window I just offset visible regions, you take the dirty screen region and pass it to every layer by converting it to it's local coordinate system. When you resize, same happens. In the end it's almost the same. I chose screen coords because of mouse_moved operations. bye, Adi.