* Change the protocol for sending the affected view tokens during an update
session to also include each view's individual update rect (in screen coords). Should actually not be mush slower than the old version, and hopefully makes it possible to have smarter BView::Draw() implementations which should make more than up for any potential speed loss. * Removed unused version of View::AddTokensForViewsInRegion(). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25879 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
50d3d63701
commit
581e67867c
@ -1154,7 +1154,6 @@ FrameMoved(origin);
|
||||
//bigtime_t now = system_time();
|
||||
//bigtime_t drawTime = 0;
|
||||
STRACE(("info:BWindow handling _UPDATE_.\n"));
|
||||
BRect updateRect;
|
||||
|
||||
fLink->StartMessage(AS_BEGIN_UPDATE);
|
||||
fInTransaction = true;
|
||||
@ -1189,36 +1188,55 @@ FrameMoved(origin);
|
||||
FrameResized(width, height);
|
||||
}
|
||||
|
||||
// read culmulated update rect (is in screen coords)
|
||||
fLink->Read<BRect>(&updateRect);
|
||||
|
||||
// read tokens for views that need to be drawn
|
||||
// NOTE: we need to read the tokens completely
|
||||
// first, or other calls would likely mess up the
|
||||
// data in the link.
|
||||
BList tokens(20);
|
||||
int32 token;
|
||||
status_t error = fLink->Read<int32>(&token);
|
||||
while (error >= B_OK && token != B_NULL_TOKEN) {
|
||||
tokens.AddItem((void*)token);
|
||||
error = fLink->Read<int32>(&token);
|
||||
// first, we cannot draw views in between reading
|
||||
// the tokens, since other communication would likely
|
||||
// mess up the data in the link.
|
||||
struct ViewUpdateInfo {
|
||||
int32 token;
|
||||
BRect updateRect;
|
||||
};
|
||||
BList infos(20);
|
||||
while (true) {
|
||||
// read next token and create/add ViewUpdateInfo
|
||||
int32 token;
|
||||
status_t error = fLink->Read<int32>(&token);
|
||||
if (error < B_OK || token == B_NULL_TOKEN)
|
||||
break;
|
||||
ViewUpdateInfo* info = new (nothrow) ViewUpdateInfo;
|
||||
if (info == NULL || !infos.AddItem(info)) {
|
||||
delete info;
|
||||
break;
|
||||
}
|
||||
info->token = token;
|
||||
// read culmulated update rect (is in screen coords)
|
||||
error = fLink->Read<BRect>(&(info->updateRect));
|
||||
if (error < B_OK)
|
||||
break;
|
||||
}
|
||||
// draw
|
||||
int32 count = tokens.CountItems();
|
||||
int32 count = infos.CountItems();
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
//bigtime_t drawStart = system_time();
|
||||
if (BView* view = _FindView((int32)tokens.ItemAtFast(i)))
|
||||
view->_Draw(updateRect);
|
||||
ViewUpdateInfo* info
|
||||
= (ViewUpdateInfo*)infos.ItemAtFast(i);
|
||||
if (BView* view = _FindView(info->token))
|
||||
view->_Draw(info->updateRect);
|
||||
else
|
||||
printf("_UPDATE_ - didn't find view by token: %ld\n", (int32)tokens.ItemAtFast(i));
|
||||
printf("_UPDATE_ - didn't find view by token: %ld\n",
|
||||
info->token);
|
||||
//drawTime += system_time() - drawStart;
|
||||
}
|
||||
// NOTE: The tokens are actually hirachically sorted,
|
||||
// so traversing the list in revers and calling
|
||||
// child->DrawAfterChildren actually works correctly
|
||||
// child->_DrawAfterChildren() actually works like intended.
|
||||
for (int32 i = count - 1; i >= 0; i--) {
|
||||
if (BView* view = _FindView((int32)tokens.ItemAtFast(i)))
|
||||
view->_DrawAfterChildren(updateRect);
|
||||
ViewUpdateInfo* info
|
||||
= (ViewUpdateInfo*)infos.ItemAtFast(i);
|
||||
if (BView* view = _FindView(info->token))
|
||||
view->_DrawAfterChildren(info->updateRect);
|
||||
delete info;
|
||||
}
|
||||
|
||||
//printf(" %ld views drawn, total Draw() time: %lld\n", count, drawTime);
|
||||
|
@ -1475,23 +1475,6 @@ View::MarkBackgroundDirty()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
View::AddTokensForViewsInRegion(BMessage* message, BRegion& region,
|
||||
BRegion* windowContentClipping)
|
||||
{
|
||||
if (!fVisible)
|
||||
return;
|
||||
|
||||
if (region.Intersects(_ScreenClipping(windowContentClipping).Frame()))
|
||||
message->AddInt32("_token", fToken);
|
||||
|
||||
for (View* child = FirstChild(); child; child = child->NextSibling()) {
|
||||
child->AddTokensForViewsInRegion(message, region,
|
||||
windowContentClipping);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
View::AddTokensForViewsInRegion(BPrivate::PortLink& link, BRegion& region,
|
||||
BRegion* windowContentClipping)
|
||||
@ -1499,17 +1482,28 @@ View::AddTokensForViewsInRegion(BPrivate::PortLink& link, BRegion& region,
|
||||
if (!fVisible)
|
||||
return;
|
||||
|
||||
IntRect screenBounds(Bounds());
|
||||
ConvertToScreen(&screenBounds);
|
||||
if (!region.Intersects((clipping_rect)screenBounds))
|
||||
return;
|
||||
{
|
||||
// NOTE: use scope in order to reduce stack space requirements
|
||||
|
||||
if (region.Intersects(_ScreenClipping(windowContentClipping).Frame()))
|
||||
link.Attach<int32>(fToken);
|
||||
// This check will prevent descending the view hierarchy
|
||||
// any further than necessary
|
||||
IntRect screenBounds(Bounds());
|
||||
ConvertToScreen(&screenBounds);
|
||||
if (!region.Intersects((clipping_rect)screenBounds))
|
||||
return;
|
||||
|
||||
for (View* child = FirstChild(); child; child = child->NextSibling()) {
|
||||
child->AddTokensForViewsInRegion(link, region, windowContentClipping);
|
||||
// Unfortunately, we intersecting another region, but otherwise
|
||||
// we couldn't provide the exact update rect to the client
|
||||
BRegion localDirty = _ScreenClipping(windowContentClipping);
|
||||
localDirty.IntersectWith(®ion);
|
||||
if (localDirty.CountRects() > 0) {
|
||||
link.Attach<int32>(fToken);
|
||||
link.Attach<BRect>(localDirty.Frame());
|
||||
}
|
||||
}
|
||||
|
||||
for (View* child = FirstChild(); child; child = child->NextSibling())
|
||||
child->AddTokensForViewsInRegion(link, region, windowContentClipping);
|
||||
}
|
||||
|
||||
|
||||
|
@ -215,10 +215,6 @@ class View {
|
||||
bool IsDesktopBackground() const
|
||||
{ return fIsDesktopBackground; }
|
||||
|
||||
void AddTokensForViewsInRegion(BMessage* message,
|
||||
BRegion& region,
|
||||
BRegion* windowContentClipping);
|
||||
|
||||
void AddTokensForViewsInRegion(BPrivate::PortLink& link,
|
||||
BRegion& region,
|
||||
BRegion* windowContentClipping);
|
||||
|
@ -1915,8 +1915,6 @@ Window::BeginUpdate(BPrivate::PortLink& link)
|
||||
link.Attach<BPoint>(fFrame.LeftTop());
|
||||
link.Attach<float>(fFrame.Width());
|
||||
link.Attach<float>(fFrame.Height());
|
||||
// append he update rect in screen coords
|
||||
link.Attach<BRect>(dirty->Frame());
|
||||
// find and attach all views that intersect with
|
||||
// the dirty region
|
||||
fTopView->AddTokensForViewsInRegion(link, *dirty, &fContentRegion);
|
||||
|
Loading…
Reference in New Issue
Block a user