Correct implementation of BView::CopyBits() in ServerWindow, implementation of CopyRegion in DisplayDriverPainter that sorts the rects topologically depending on direction and does the copy in place, obtaining a speedup of about 250%. TODO: extract the sorting algorithm so that it can be reused for the hardware accelerated version later.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12468 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2005-04-26 13:50:34 +00:00
parent a2f1c2e02d
commit 93a2cfd43c
5 changed files with 306 additions and 383 deletions
+40 -32
View File
@@ -522,49 +522,57 @@ void ServerWindow::DispatchMessage(int32 code, LinkMsgReader &link)
}
case AS_LAYER_COPY_BITS:
{
BRect src;
BRect dest;
link.Read<BRect>(&src);
link.Read<BRect>(&dest);
// NOTE: The correct behaviour is this:
// * The region that is copied is the
// src rectangle, no matter if it fits
// into the dest rectangle. It is copied
// by the offset dest.LeftTop() - src.LeftTop()
// * The dest rectangle is used for invalidation:
// Any area in the dest rectangle that could
// into the dst rectangle. It is copied
// by the offset dst.LeftTop() - src.LeftTop()
// * The dst rectangle is used for invalidation:
// Any area in the dst rectangle that could
// not be copied from src (because either the
// src rectangle was not big enough, or because there
// were parts cut off by the current layer clipping),
// are triggering BView::Draw() to be called
// and for these parts only.
// TODO: The DisplayDriver::CopyBits() call needs
// to get a BRegion and an offset by which to copy
// all the rects in that region. The region is calculated as
// * The src rectangle minus the currect clipping of the layer
// * minus the part of the region that is outside the layer
// when the region is translated by the offset!
// Then, an invalidation needs to be triggered for the
// following region: the dest rectangle minus the
// region we calculated in step one translated by the
// offset.
// By implementing it this way, we don't mix the update
// triggering with the actual graphical operation in
// DisplayDriver. I know that normally DisplayDriver takes
// care of the clipping, but this is different, because
// CopyBits() is the only drawing call that can trigger
// invalidation.
// TODO: In DisplayDriver, implement the described CopyBits()
// version. Also, the current implementation is wrong because it
// clips the source rectangle to the dest rectangle.
BRect src;
BRect dst;
link.Read<BRect>(&src);
link.Read<BRect>(&dst);
// TODO: Are origin and scale handled in this conversion?
src = cl->ConvertToTop(src);
dest = cl->ConvertToTop(dest);
dst = cl->ConvertToTop(dst);
int32 xOffset = (int32)(dst.left - src.left);
int32 yOffset = (int32)(dst.top - src.top);
// the region that is going to be copied
BRegion copyRegion(src);
// apply the current clipping of the layer
copyRegion.IntersectWith(&cl->fVisible);
// offset the region to the destination
// and apply the current clipping there as well
copyRegion.OffsetBy(xOffset, yOffset);
copyRegion.IntersectWith(&cl->fVisible);
// the region at the destination that needs invalidation
BRegion invalidRegion(dst);
// exclude the region drawn by the copy operation
invalidRegion.Exclude(&copyRegion);
// apply the current clipping as well
invalidRegion.IntersectWith(&cl->fVisible);
// move the region back for the actual operation
copyRegion.OffsetBy(-xOffset, -yOffset);
cl->fDriver->CopyRegion(&copyRegion, xOffset, yOffset);
// trigger the redraw
myRootLayer->GoRedraw(fWinBorder, invalidRegion);
cl->fDriver->CopyBits(src, dest, cl->fLayerData);
break;
}
case AS_SET_CURRENT_LAYER: