stress testing. It shows that for 40 open windows, the newerClipping design takes 3.5 times less time in the root layer thread compared to the newClipping design. On average, it is about 8.7 times faster. The goal of the redesign, to move the heavier computation from the root layer thread into each window thread, seems achieved, since even with 100 open windows, moving a window does not start any lagging. By removing the global dirty region in Desktop, I think this can be further improved.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15183 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2005-11-27 00:18:08 +00:00
parent 05644959e1
commit f51806635b
6 changed files with 345 additions and 37 deletions

View File

@ -156,10 +156,14 @@ void MyView::MouseMoved(BPoint where, uint32 code, const BMessage *a_message)
{
if (fMovingLayer)
{
if (fIsResize)
bigtime_t now = system_time();
if (fIsResize) {
fMovingLayer->ResizeBy(dx, dy);
else
printf("resizing: %lld\n", system_time() - now);
} else {
fMovingLayer->MoveBy(dx, dy);
printf("moving: %lld\n", system_time() - now);
}
}
}
}

View File

@ -4,6 +4,7 @@
#include <View.h>
#include <Region.h>
#include <Rect.h>
#include <String.h>
#include <stdio.h>
#include <stdlib.h>
@ -35,6 +36,8 @@ public:
~clsMainWindow();
virtual bool QuitRequested();
void AddWindow(BRect frame, const char* name);
void test2();
void test1();
private:
MyView *fView;
@ -79,6 +82,152 @@ bool clsMainWindow::QuitRequested()
return BWindow::QuitRequested();
}
// AddWindow
void
clsMainWindow::AddWindow(BRect frame, const char* name)
{
Layer* topLayer = fView->topLayer;
WinBorder* window = new WinBorder(frame, name, B_FOLLOW_NONE, B_FULL_UPDATE_ON_RESIZE,
(rgb_color){ 255, 203, 0, 255 });
topLayer->AddLayer(window);
// add a coupld children
frame.OffsetTo(B_ORIGIN);
frame.InsetBy(5.0, 5.0);
if (frame.IsValid()) {
Layer* layer1 = new Layer(frame, "View 1", B_FOLLOW_ALL,
B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 180, 180, 180, 255 });
frame.OffsetTo(B_ORIGIN);
frame.InsetBy(15.0, 15.0);
if (frame.IsValid()) {
BRect f = frame;
f.bottom = f.top + f.Height() / 3 - 3;
f.right = f.left + f.Width() / 3 - 3;
// top row of views
Layer* layer;
layer = new Layer(f, "View", B_FOLLOW_LEFT | B_FOLLOW_TOP,
B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 120, 120, 120, 255 });
layer1->AddLayer(layer);
f.OffsetBy(f.Width() + 6, 0);
layer = new Layer(f, "View", B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP,
B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 120, 120, 120, 255 });
layer1->AddLayer(layer);
f.OffsetBy(f.Width() + 6, 0);
layer = new Layer(f, "View", B_FOLLOW_RIGHT | B_FOLLOW_TOP,
B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 120, 120, 120, 255 });
layer1->AddLayer(layer);
// middle row of views
f = frame;
f.bottom = f.top + f.Height() / 3 - 3;
f.right = f.left + f.Width() / 3 - 3;
f.OffsetBy(0, f.Height() + 6);
layer = new Layer(f, "View", B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM,
B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 120, 120, 120, 255 });
layer1->AddLayer(layer);
f.OffsetBy(f.Width() + 6, 0);
layer = new Layer(f, "View", B_FOLLOW_ALL,
B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 120, 120, 120, 255 });
layer1->AddLayer(layer);
f.OffsetBy(f.Width() + 6, 0);
layer = new Layer(f, "View", B_FOLLOW_RIGHT | B_FOLLOW_TOP_BOTTOM,
B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 120, 120, 120, 255 });
layer1->AddLayer(layer);
// bottom row of views
f = frame;
f.bottom = f.top + f.Height() / 3 - 3;
f.right = f.left + f.Width() / 3 - 3;
f.OffsetBy(0, 2 * f.Height() + 12);
layer = new Layer(f, "View", B_FOLLOW_LEFT | B_FOLLOW_BOTTOM,
B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 120, 120, 120, 255 });
layer1->AddLayer(layer);
f.OffsetBy(f.Width() + 6, 0);
layer = new Layer(f, "View", B_FOLLOW_LEFT_RIGHT | B_FOLLOW_BOTTOM,
B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 120, 120, 120, 255 });
layer1->AddLayer(layer);
f.OffsetBy(f.Width() + 6, 0);
layer = new Layer(f, "View", B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM,
B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 120, 120, 120, 255 });
layer1->AddLayer(layer);
}
window->AddLayer(layer1);
}
BRegion temp;
window->GetWantedRegion(temp);
topLayer->RebuildVisibleRegions(temp, window);
}
// test2
void
clsMainWindow::test2()
{
BRect frame(20, 20, 330, 230);
for (int32 i = 0; i < 20; i++) {
BString name("Window ");
frame.OffsetBy(20, 15);
name << i + 1;
AddWindow(frame, name.String());
}
/*
frame.Set(10, 80, 320, 290);
for (int32 i = 20; i < 40; i++) {
BString name("Window ");
frame.OffsetBy(20, 15);
name << i + 1;
AddWindow(frame, name.String());
}
frame.Set(20, 140, 330, 230);
for (int32 i = 40; i < 60; i++) {
BString name("Window ");
frame.OffsetBy(20, 15);
name << i + 1;
AddWindow(frame, name.String());
}
frame.Set(20, 200, 330, 230);
for (int32 i = 60; i < 80; i++) {
BString name("Window ");
frame.OffsetBy(20, 15);
name << i + 1;
AddWindow(frame, name.String());
}
frame.Set(20, 260, 330, 230);
// 99 windows are ok, the 100th looper does not run anymore,
// I guess I'm hitting a BeOS limit (max loopers per app?)
for (int32 i = 80; i < 99; i++) {
BString name("Window ");
frame.OffsetBy(20, 15);
name << i + 1;
AddWindow(frame, name.String());
}*/
fView->RequestRedraw();
}
void clsMainWindow::test1()
{
Layer *topLayer = fView->topLayer;
@ -198,6 +347,55 @@ void clsMainWindow::test1()
0, c);
lay21->AddLayer(lay22);
WinBorder *wb3 = new WinBorder(BRect(20,20,300,220), "wb3", B_FOLLOW_NONE, B_FULL_UPDATE_ON_RESIZE, c);
topLayer->AddLayer(wb3);
// same size as wb1
lay1 = new Layer(BRect(0,0,280,200), "lay1", B_FOLLOW_ALL, 0, c);
wb3->AddLayer(lay1);
WinBorder *wb4 = new WinBorder(BRect(20,20,300,220), "wb4", B_FOLLOW_NONE, B_FULL_UPDATE_ON_RESIZE, c);
topLayer->AddLayer(wb4);
// same size as wb1
lay1 = new Layer(BRect(0,0,280,200), "lay1", B_FOLLOW_ALL, 0, c);
wb4->AddLayer(lay1);
WinBorder *wb5 = new WinBorder(BRect(20,20,300,220), "wb5", B_FOLLOW_NONE, B_FULL_UPDATE_ON_RESIZE, c);
topLayer->AddLayer(wb5);
// same size as wb1
lay1 = new Layer(BRect(0,0,280,200), "lay1", B_FOLLOW_ALL, 0, c);
wb5->AddLayer(lay1);
WinBorder *wb6 = new WinBorder(BRect(20,20,300,220), "wb6", B_FOLLOW_NONE, B_FULL_UPDATE_ON_RESIZE, c);
topLayer->AddLayer(wb6);
// same size as wb1
lay1 = new Layer(BRect(0,0,280,200), "lay1", B_FOLLOW_ALL, 0, c);
wb6->AddLayer(lay1);
WinBorder *wb7 = new WinBorder(BRect(20,20,300,220), "wb7", B_FOLLOW_NONE, B_FULL_UPDATE_ON_RESIZE, c);
topLayer->AddLayer(wb7);
// same size as wb1
lay1 = new Layer(BRect(0,0,280,200), "lay1", B_FOLLOW_ALL, 0, c);
wb7->AddLayer(lay1);
WinBorder *wb8 = new WinBorder(BRect(20,20,300,220), "wb8", B_FOLLOW_NONE, B_FULL_UPDATE_ON_RESIZE, c);
topLayer->AddLayer(wb8);
// same size as wb1
lay1 = new Layer(BRect(0,0,280,200), "lay1", B_FOLLOW_ALL, 0, c);
wb8->AddLayer(lay1);
WinBorder *wb9 = new WinBorder(BRect(20,20,300,220), "wb9", B_FOLLOW_NONE, B_FULL_UPDATE_ON_RESIZE, c);
topLayer->AddLayer(wb9);
// same size as wb1
lay1 = new Layer(BRect(0,0,280,200), "lay1", B_FOLLOW_ALL, 0, c);
wb9->AddLayer(lay1);
WinBorder *wb10 = new WinBorder(BRect(20,20,300,220), "wb10", B_FOLLOW_NONE, B_FULL_UPDATE_ON_RESIZE, c);
topLayer->AddLayer(wb10);
// same size as wb1
lay1 = new Layer(BRect(0,0,280,200), "lay1", B_FOLLOW_ALL, 0, c);
wb10->AddLayer(lay1);
//---------
BRegion temp;
@ -207,6 +405,31 @@ void clsMainWindow::test1()
wb2->GetWantedRegion(temp);
topLayer->RebuildVisibleRegions(temp, wb2);
wb3->GetWantedRegion(temp);
topLayer->RebuildVisibleRegions(temp, wb3);
wb4->GetWantedRegion(temp);
topLayer->RebuildVisibleRegions(temp, wb4);
wb5->GetWantedRegion(temp);
topLayer->RebuildVisibleRegions(temp, wb5);
wb6->GetWantedRegion(temp);
topLayer->RebuildVisibleRegions(temp, wb6);
wb7->GetWantedRegion(temp);
topLayer->RebuildVisibleRegions(temp, wb7);
wb8->GetWantedRegion(temp);
topLayer->RebuildVisibleRegions(temp, wb8);
wb9->GetWantedRegion(temp);
topLayer->RebuildVisibleRegions(temp, wb9);
wb10->GetWantedRegion(temp);
topLayer->RebuildVisibleRegions(temp, wb10);
fView->RequestRedraw();
snooze(1000000);
@ -256,7 +479,7 @@ int main()
clsMainWindow *win = new clsMainWindow("clipping");
win->Show();
win->test1();
win->test2();
be_app->Run();
delete be_app;

View File

@ -159,13 +159,13 @@ Desktop::MouseMoved(BPoint where, uint32 code, const BMessage* dragMessage)
if (dx != 0 || dy != 0) {
if (fClickedWindow) {
//bigtime_t now = system_time();
bigtime_t now = system_time();
if (fResizing) {
ResizeWindowBy(fClickedWindow, dx, dy);
//printf("resizing: %lld\n", system_time() - now);
printf("resizing: %lld\n", system_time() - now);
} else {
MoveWindowBy(fClickedWindow, dx, dy);
//printf("moving: %lld\n", system_time() - now);
printf("moving: %lld\n", system_time() - now);
}
}
}

View File

@ -458,7 +458,7 @@ ViewLayer::ResizeBy(int32 x, int32 y, BRegion* dirtyRegion)
if (dirty.CountRects() > 0) {
// exclude children, they are expected to
// have included their own dirty regions
// include their own dirty regions in ParentResized()
for (ViewLayer* child = FirstChild(); child; child = NextChild()) {
BRect previousChildVisible(child->Frame() & oldBounds & Bounds());
if (dirty.Frame().Intersects(previousChildVisible)) {
@ -523,13 +523,14 @@ ViewLayer::ParentResized(int32 x, int32 y, BRegion* dirtyRegion)
newFrame.bottom += y / 2;
if (newFrame != fFrame) {
// MoveBy will change fFrame, so cache it
BRect oldFrame = fFrame;
MoveBy(newFrame.left - oldFrame.left,
newFrame.top - oldFrame.top, dirtyRegion);
// careful, MoveBy will change fFrame
int32 widthDiff = (int32)(newFrame.Width() - fFrame.Width());
int32 heightDiff = (int32)(newFrame.Height() - fFrame.Height());
ResizeBy(newFrame.Width() - oldFrame.Width(),
newFrame.Height() - oldFrame.Height(), dirtyRegion);
MoveBy(newFrame.left - fFrame.left,
newFrame.top - fFrame.top, dirtyRegion);
ResizeBy(widthDiff, heightDiff, dirtyRegion);
}
}

View File

@ -87,23 +87,72 @@ Window::AddWindow(BRect frame, const char* name)
frame.OffsetTo(B_ORIGIN);
frame.InsetBy(15.0, 15.0);
if (frame.IsValid()) {
frame.bottom = (frame.top + frame.bottom) / 2 - 5;
ViewLayer* layer2 = new ViewLayer(frame, "View 2",
B_FOLLOW_ALL,
0,
(rgb_color){ 120, 120, 120, 255 });
frame.OffsetBy(0.0, frame.Height() + 10);
BRect f = frame;
f.bottom = f.top + f.Height() / 3 - 3;
f.right = f.left + f.Width() / 3 - 3;
ViewLayer* layer3 = new ViewLayer(frame, "View 3",
B_FOLLOW_BOTTOM,
0,
(rgb_color){ 120, 120, 120, 255 });
// top row of views
ViewLayer* layer;
layer = new ViewLayer(f, "View", B_FOLLOW_LEFT | B_FOLLOW_TOP,
B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 120, 120, 120, 255 });
layer1->AddChild(layer);
layer1->AddChild(layer2);
layer1->AddChild(layer3);
f.OffsetBy(f.Width() + 6, 0);
layer = new ViewLayer(f, "View", B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP,
B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 120, 120, 120, 255 });
layer1->AddChild(layer);
f.OffsetBy(f.Width() + 6, 0);
layer = new ViewLayer(f, "View", B_FOLLOW_RIGHT | B_FOLLOW_TOP,
B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 120, 120, 120, 255 });
layer1->AddChild(layer);
// middle row of views
f = frame;
f.bottom = f.top + f.Height() / 3 - 3;
f.right = f.left + f.Width() / 3 - 3;
f.OffsetBy(0, f.Height() + 6);
layer = new ViewLayer(f, "View", B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM,
B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 120, 120, 120, 255 });
layer1->AddChild(layer);
f.OffsetBy(f.Width() + 6, 0);
layer = new ViewLayer(f, "View", B_FOLLOW_ALL,
B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 120, 120, 120, 255 });
layer1->AddChild(layer);
f.OffsetBy(f.Width() + 6, 0);
layer = new ViewLayer(f, "View", B_FOLLOW_RIGHT | B_FOLLOW_TOP_BOTTOM,
B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 120, 120, 120, 255 });
layer1->AddChild(layer);
// bottom row of views
f = frame;
f.bottom = f.top + f.Height() / 3 - 3;
f.right = f.left + f.Width() / 3 - 3;
f.OffsetBy(0, 2 * f.Height() + 12);
layer = new ViewLayer(f, "View", B_FOLLOW_LEFT | B_FOLLOW_BOTTOM,
B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 120, 120, 120, 255 });
layer1->AddChild(layer);
f.OffsetBy(f.Width() + 6, 0);
layer = new ViewLayer(f, "View", B_FOLLOW_LEFT_RIGHT | B_FOLLOW_BOTTOM,
B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 120, 120, 120, 255 });
layer1->AddChild(layer);
f.OffsetBy(f.Width() + 6, 0);
layer = new ViewLayer(f, "View", B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM,
B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 120, 120, 120, 255 });
layer1->AddChild(layer);
}
window->AddChild(layer1);
@ -120,16 +169,47 @@ Window::AddWindow(BRect frame, const char* name)
void
Window::Test()
{
AddWindow(BRect(20, 20, 80, 80), "Window 1");
AddWindow(BRect(60, 60, 220, 180), "Window 2");
AddWindow(BRect(120, 160, 500, 380), "Window 3");
AddWindow(BRect(40, 210, 400, 280), "Window 4");
AddWindow(BRect(180, 410, 400, 680), "Window 5");
AddWindow(BRect(30, 350, 100, 440), "Window 6");
AddWindow(BRect(80, 10, 200, 120), "Window 7");
AddWindow(BRect(480, 40, 670, 320), "Window 8");
AddWindow(BRect(250, 500, 310, 600), "Window 9");
AddWindow(BRect(130, 450, 230, 500), "Window 10");
BRect frame(20, 20, 330, 230);
for (int32 i = 0; i < 20; i++) {
BString name("Window ");
frame.OffsetBy(20, 15);
name << i + 1;
AddWindow(frame, name.String());
}
frame.Set(10, 80, 320, 290);
for (int32 i = 20; i < 40; i++) {
BString name("Window ");
frame.OffsetBy(20, 15);
name << i + 1;
AddWindow(frame, name.String());
}
/* frame.Set(20, 140, 330, 230);
for (int32 i = 40; i < 60; i++) {
BString name("Window ");
frame.OffsetBy(20, 15);
name << i + 1;
AddWindow(frame, name.String());
}
frame.Set(20, 200, 330, 230);
for (int32 i = 60; i < 80; i++) {
BString name("Window ");
frame.OffsetBy(20, 15);
name << i + 1;
AddWindow(frame, name.String());
}
frame.Set(20, 260, 330, 230);
// 99 windows are ok, the 100th looper does not run anymore,
// I guess I'm hitting a BeOS limit (max loopers per app?)
for (int32 i = 80; i < 99; i++) {
BString name("Window ");
frame.OffsetBy(20, 15);
name << i + 1;
AddWindow(frame, name.String());
}*/
}
// main