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:
@@ -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(©Region);
|
||||
// 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(©Region, xOffset, yOffset);
|
||||
|
||||
// trigger the redraw
|
||||
myRootLayer->GoRedraw(fWinBorder, invalidRegion);
|
||||
|
||||
cl->fDriver->CopyBits(src, dest, cl->fLayerData);
|
||||
|
||||
break;
|
||||
}
|
||||
case AS_SET_CURRENT_LAYER:
|
||||
|
||||
Reference in New Issue
Block a user