* made transfering the pending to the current update session a bit faster

by toggling pointers instead of assigning/transfering regions


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23272 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2008-01-06 20:20:37 +00:00
parent c177064158
commit 052ae287b0
2 changed files with 35 additions and 42 deletions
+32 -38
View File
@@ -107,8 +107,8 @@ WindowLayer::WindowLayer(const BRect& frame, const char *name,
fLastMousePosition(0.0, 0.0), fLastMousePosition(0.0, 0.0),
fLastMoveTime(0), fLastMoveTime(0),
fCurrentUpdateSession(), fCurrentUpdateSession(&fUpdateSessions[0]),
fPendingUpdateSession(), fPendingUpdateSession(&fUpdateSessions[1]),
fUpdateRequested(false), fUpdateRequested(false),
fInUpdate(false), fInUpdate(false),
@@ -293,10 +293,10 @@ WindowLayer::MoveBy(int32 x, int32 y)
if (fContentRegionValid) if (fContentRegionValid)
fContentRegion.OffsetBy(x, y); fContentRegion.OffsetBy(x, y);
if (fCurrentUpdateSession.IsUsed()) if (fCurrentUpdateSession->IsUsed())
fCurrentUpdateSession.MoveBy(x, y); fCurrentUpdateSession->MoveBy(x, y);
if (fPendingUpdateSession.IsUsed()) if (fPendingUpdateSession->IsUsed())
fPendingUpdateSession.MoveBy(x, y); fPendingUpdateSession->MoveBy(x, y);
fEffectiveDrawingRegionValid = false; fEffectiveDrawingRegionValid = false;
@@ -437,10 +437,12 @@ WindowLayer::CopyContents(BRegion* region, int32 xOffset, int32 yOffset)
// move along the already dirty regions that are common // move along the already dirty regions that are common
// with the region that we could copy // with the region that we could copy
_ShiftPartOfRegion(&fDirtyRegion, region, xOffset, yOffset); _ShiftPartOfRegion(&fDirtyRegion, region, xOffset, yOffset);
if (fPendingUpdateSession.IsUsed()) if (fPendingUpdateSession->IsUsed()) {
_ShiftPartOfRegion(&fPendingUpdateSession.DirtyRegion(), region, xOffset, yOffset); _ShiftPartOfRegion(&(fPendingUpdateSession->DirtyRegion()), region,
xOffset, yOffset);
}
if (fCurrentUpdateSession.IsUsed()) { if (fCurrentUpdateSession->IsUsed()) {
// if there are parts in the current update session // if there are parts in the current update session
// that intersect with the copied region, we cannot // that intersect with the copied region, we cannot
// simply shift them as with the other dirty regions // simply shift them as with the other dirty regions
@@ -449,10 +451,10 @@ WindowLayer::CopyContents(BRegion* region, int32 xOffset, int32 yOffset)
// new dirty region instead // new dirty region instead
BRegion* common = fRegionPool.GetRegion(*region); BRegion* common = fRegionPool.GetRegion(*region);
// see if there is a common part at all // see if there is a common part at all
common->IntersectWith(&fCurrentUpdateSession.DirtyRegion()); common->IntersectWith(&fCurrentUpdateSession->DirtyRegion());
if (common->CountRects() > 0) { if (common->CountRects() > 0) {
// cut the common part from the region // cut the common part from the region
fCurrentUpdateSession.DirtyRegion().Exclude(common); fCurrentUpdateSession->DirtyRegion().Exclude(common);
newDirty->Include(common); newDirty->Include(common);
} }
fRegionPool.Recycle(common); fRegionPool.Recycle(common);
@@ -549,10 +551,10 @@ WindowLayer::GetEffectiveDrawingRegion(ViewLayer* layer, BRegion& region)
if (fUpdateRequested && !fInUpdate) { if (fUpdateRequested && !fInUpdate) {
// we requested an update, but the client has not started it yet, // we requested an update, but the client has not started it yet,
// so it is only allowed to draw outside the pending update sessions region // so it is only allowed to draw outside the pending update sessions region
fEffectiveDrawingRegion.Exclude(&fPendingUpdateSession.DirtyRegion()); fEffectiveDrawingRegion.Exclude(&(fPendingUpdateSession->DirtyRegion()));
} else if (fInUpdate) { } else if (fInUpdate) {
// enforce the dirty region of the update session // enforce the dirty region of the update session
fEffectiveDrawingRegion.IntersectWith(&fCurrentUpdateSession.DirtyRegion()); fEffectiveDrawingRegion.IntersectWith(&fCurrentUpdateSession->DirtyRegion());
} else { } else {
// not in update, the view can draw everywhere // not in update, the view can draw everywhere
//printf("WindowLayer(%s)::GetEffectiveDrawingRegion(for %s) - outside update\n", Title(), layer->Name()); //printf("WindowLayer(%s)::GetEffectiveDrawingRegion(for %s) - outside update\n", Title(), layer->Name());
@@ -1679,12 +1681,12 @@ WindowLayer::_TriggerContentRedraw(BRegion& dirtyContentRegion)
if (IsVisible() && dirtyContentRegion.CountRects() > 0) { if (IsVisible() && dirtyContentRegion.CountRects() > 0) {
// put this into the pending dirty region // put this into the pending dirty region
// to eventually trigger a client redraw // to eventually trigger a client redraw
bool wasExpose = fPendingUpdateSession.IsExpose(); bool wasExpose = fPendingUpdateSession->IsExpose();
BRegion* backgroundClearingRegion = &dirtyContentRegion; BRegion* backgroundClearingRegion = &dirtyContentRegion;
_TransferToUpdateSession(&dirtyContentRegion); _TransferToUpdateSession(&dirtyContentRegion);
if (fPendingUpdateSession.IsExpose()) { if (fPendingUpdateSession->IsExpose()) {
if (!fContentRegionValid) if (!fContentRegionValid)
_UpdateContentRegion(); _UpdateContentRegion();
@@ -1692,7 +1694,7 @@ WindowLayer::_TriggerContentRedraw(BRegion& dirtyContentRegion)
// there was suddenly added a dirty region // there was suddenly added a dirty region
// caused by exposing content, we need to clear // caused by exposing content, we need to clear
// the entire background // the entire background
backgroundClearingRegion = &fPendingUpdateSession.DirtyRegion(); backgroundClearingRegion = &(fPendingUpdateSession->DirtyRegion());
} }
if (fDrawingEngine->LockParallelAccess()) { if (fDrawingEngine->LockParallelAccess()) {
@@ -1767,10 +1769,10 @@ WindowLayer::_TransferToUpdateSession(BRegion* contentDirtyRegion)
//snooze(10000); //snooze(10000);
// add to pending // add to pending
fPendingUpdateSession.SetUsed(true); fPendingUpdateSession->SetUsed(true);
// if (!fPendingUpdateSession.IsExpose()) // if (!fPendingUpdateSession->IsExpose())
fPendingUpdateSession.AddCause(fDirtyCause); fPendingUpdateSession->AddCause(fDirtyCause);
fPendingUpdateSession.Include(contentDirtyRegion); fPendingUpdateSession->Include(contentDirtyRegion);
// clip pending update session from current // clip pending update session from current
// update session, it makes no sense to draw stuff // update session, it makes no sense to draw stuff
@@ -1784,8 +1786,8 @@ WindowLayer::_TransferToUpdateSession(BRegion* contentDirtyRegion)
// until everything settles down. Potentially, this could even give // until everything settles down. Potentially, this could even give
// the impression of faster updates, even though they might look // the impression of faster updates, even though they might look
// wrong when looked at closer, but will fix themselves shortly later // wrong when looked at closer, but will fix themselves shortly later
// if (fCurrentUpdateSession.IsUsed() && fCurrentUpdateSession.IsExpose()) { // if (fCurrentUpdateSession->IsUsed() && fCurrentUpdateSession->IsExpose()) {
// fCurrentUpdateSession.Exclude(contentDirtyRegion); // fCurrentUpdateSession->Exclude(contentDirtyRegion);
// fEffectiveDrawingRegionValid = false; // fEffectiveDrawingRegionValid = false;
// } // }
@@ -1823,10 +1825,11 @@ WindowLayer::BeginUpdate(BPrivate::PortLink& link)
if (fUpdateRequested) { if (fUpdateRequested) {
// make the pending update session the current update session // make the pending update session the current update session
// TODO: the toggling between the update sessions is too // (toggle the pointers)
// expensive, optimize with some pointer tricks UpdateSession* temp = fCurrentUpdateSession;
fCurrentUpdateSession = fPendingUpdateSession; fCurrentUpdateSession = fPendingUpdateSession;
fPendingUpdateSession.SetUsed(false); fPendingUpdateSession = temp;
fPendingUpdateSession->SetUsed(false);
// all drawing command from the client // all drawing command from the client
// will have the dirty region from the update // will have the dirty region from the update
// session enforced // session enforced
@@ -1842,7 +1845,7 @@ WindowLayer::BeginUpdate(BPrivate::PortLink& link)
_UpdateContentRegion(); _UpdateContentRegion();
BRegion* dirty = fRegionPool.GetRegion( BRegion* dirty = fRegionPool.GetRegion(
fCurrentUpdateSession.DirtyRegion()); fCurrentUpdateSession->DirtyRegion());
if (!dirty) { if (!dirty) {
link.StartMessage(B_ERROR); link.StartMessage(B_ERROR);
link.Flush(); link.Flush();
@@ -1875,7 +1878,7 @@ WindowLayer::BeginUpdate(BPrivate::PortLink& link)
link.Attach<int32>(B_NULL_TOKEN); link.Attach<int32>(B_NULL_TOKEN);
link.Flush(); link.Flush();
if (!fCurrentUpdateSession.IsExpose() && fDrawingEngine->LockParallelAccess()) { if (!fCurrentUpdateSession->IsExpose() && fDrawingEngine->LockParallelAccess()) {
//fDrawingEngine->FillRegion(dirty, (rgb_color){ 255, 0, 0, 255 }); //fDrawingEngine->FillRegion(dirty, (rgb_color){ 255, 0, 0, 255 });
fDrawingEngine->SuspendAutoSync(); fDrawingEngine->SuspendAutoSync();
@@ -1903,12 +1906,12 @@ WindowLayer::EndUpdate()
// NOTE: see comment in _BeginUpdate() // NOTE: see comment in _BeginUpdate()
if (fInUpdate) { if (fInUpdate) {
fCurrentUpdateSession.SetUsed(false); fCurrentUpdateSession->SetUsed(false);
fInUpdate = false; fInUpdate = false;
fEffectiveDrawingRegionValid = false; fEffectiveDrawingRegionValid = false;
} }
if (fPendingUpdateSession.IsUsed()) { if (fPendingUpdateSession->IsUsed()) {
// send this to client // send this to client
_SendUpdateMessage(); _SendUpdateMessage();
} else { } else {
@@ -2054,12 +2057,3 @@ WindowLayer::UpdateSession::AddCause(uint8 cause)
} }
WindowLayer::UpdateSession&
WindowLayer::UpdateSession::operator=(const WindowLayer::UpdateSession& other)
{
fDirtyRegion = other.fDirtyRegion;
fInUse = other.fInUse;
fCause = other.fCause;
return *this;
}
+3 -4
View File
@@ -320,8 +320,6 @@ class WindowLayer {
inline bool IsRequest() const inline bool IsRequest() const
{ return fCause & UPDATE_REQUEST; } { return fCause & UPDATE_REQUEST; }
UpdateSession& operator=(const UpdateSession& other);
private: private:
BRegion fDirtyRegion; BRegion fDirtyRegion;
bool fInUse; bool fInUse;
@@ -330,8 +328,9 @@ class WindowLayer {
BRegion fDecoratorRegion; BRegion fDecoratorRegion;
UpdateSession fCurrentUpdateSession; UpdateSession fUpdateSessions[2];
UpdateSession fPendingUpdateSession; UpdateSession* fCurrentUpdateSession;
UpdateSession* fPendingUpdateSession;
// these two flags are supposed to ensure a sane // these two flags are supposed to ensure a sane
// and consistent update session // and consistent update session
bool fUpdateRequested : 1; bool fUpdateRequested : 1;