* removed superflous LockSingleWindow() from WindowLayer::MoveBy()

and ResizeBy()
* WindowLayer::SetSizeLimits() needs to be called with the
  AllWindows lock held
* I was observing weird behaviour with "unclickable" windows
  that I might have fixed by explicitly excluding invisible
  windows from Desktop::WindowAt(), there might be something
  wrong with the "current" window list though, Axel would know
* finally found the problem with "delayed background clearing"
* enabled delayed background clearing and removed unnecessary
  code. It should be more efficient, since it clears larger
  areas at once, and it solves the problem of views unable to
  draw into regions that are pending for another update - among
  other things, updates in resizing windows are more fluent, 
  especially for B_FULL_UPDATE_ON_RESIZE views. "Cut off" scroll
  bars should no longer appear when the view being scrolled takes
  too long to redraw.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15714 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2005-12-29 14:15:59 +00:00
parent 6c5611a064
commit cd2b129d07
7 changed files with 83 additions and 61 deletions
+2 -2
View File
@@ -1583,14 +1583,14 @@ Desktop::SetWindowTitle(WindowLayer *window, const char* title)
/*!
Returns the window under the mouse cursor.
You need to have the window write lock acquired when calling this method.
You need to have acquired the All Windows lock when calling this method.
*/
WindowLayer*
Desktop::WindowAt(BPoint where)
{
for (WindowLayer* window = _CurrentWindows().LastWindow(); window;
window = window->PreviousWindow(fCurrentWorkspace)) {
if (window->VisibleRegion().Contains(where))
if (window->IsVisible() && window->VisibleRegion().Contains(where))
return window;
}
+5 -4
View File
@@ -854,10 +854,11 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
link.Read<int32>(&minHeight);
link.Read<int32>(&maxHeight);
*/
// TODO: setting size limits can change the window size, and therefore,
// it should be done by the Desktop class as well.
fWindowLayer->SetSizeLimits(minWidth, maxWidth,
minHeight, maxHeight);
if (fDesktop->LockAllWindows()) {
fWindowLayer->SetSizeLimits(minWidth, maxWidth,
minHeight, maxHeight);
fDesktop->UnlockAllWindows();
}
// and now, sync the client to the limits that we were able to enforce
fWindowLayer->GetSizeLimits(&minWidth, &maxWidth,
+21 -18
View File
@@ -53,6 +53,16 @@
using std::nothrow;
// if the background clearing is delayed until
// the client draws the view, we have less flickering
// when contents have to be redrawn because of resizing
// a window or because the client invalidates parts.
// when redrawing something that has been exposed from underneath
// other windows, the other window will be seen longer at
// its previous position though if the exposed parts are not
// cleared right away. maybe there ought to be a flag in
// the update session, which tells us the cause of the update
#define DELAYED_BACKGROUND_CLEARING 1
WindowLayer::WindowLayer(const BRect& frame, const char *name,
window_look look, window_feel feel,
@@ -291,7 +301,7 @@ WindowLayer::MoveBy(int32 x, int32 y)
{
// this function is only called from the desktop thread
if ((x == 0 && y == 0) || !ReadLockWindows())
if (x == 0 && y == 0)
return;
fWindow->HandleDirectConnection(B_DIRECT_STOP);
@@ -330,8 +340,6 @@ WindowLayer::MoveBy(int32 x, int32 y)
msg.AddInt64("when", system_time());
msg.AddPoint("where", fFrame.LeftTop());
fWindow->SendMessageToClient(&msg);
ReadUnlockWindows();
}
@@ -357,7 +365,7 @@ WindowLayer::ResizeBy(int32 x, int32 y, BRegion* dirtyRegion)
x = wantWidth - fFrame.IntegerWidth();
y = wantHeight - fFrame.IntegerHeight();
if ((x == 0 && y == 0) || !ReadLockWindows())
if (x == 0 && y == 0)
return;
fWindow->HandleDirectConnection(B_DIRECT_STOP);
@@ -400,8 +408,6 @@ WindowLayer::ResizeBy(int32 x, int32 y, BRegion* dirtyRegion)
msg.AddInt32("width", frame.IntegerWidth());
msg.AddInt32("height", frame.IntegerHeight());
fWindow->SendMessageToClient(&msg);
ReadUnlockWindows();
}
@@ -1561,8 +1567,9 @@ WindowLayer::_TriggerContentRedraw(BRegion& dirtyContentRegion)
_TransferToUpdateSession(&dirtyContentRegion);
#if DELAYED_BACKGROUND_CLEARING
if (!fTopLayer->IsBackgroundDirty())
fTopLayer->MarkBackgroundDirty();
// NOTE: currently not used, might come in handy later though
// if (!fTopLayer->IsBackgroundDirty())
// fTopLayer->MarkBackgroundDirty();
#else
if (!fContentRegionValid)
_UpdateContentRegion();
@@ -1691,18 +1698,14 @@ WindowLayer::BeginUpdate()
// command from the client during an update
// (ViewLayer::IsBackgroundDirty() can be used
// for this)
if (fDrawingEngine->Lock()) {
if (!fContentRegionValid)
_UpdateContentRegion();
BRegion dirty(fCurrentUpdateSession.DirtyRegion());
dirty.IntersectWith(&VisibleContentRegion());
if (!fContentRegionValid)
_UpdateContentRegion();
fTopLayer->Draw(fDrawingEngine, &dirty,
&fContentRegion, true);
BRegion dirty(fCurrentUpdateSession.DirtyRegion());
dirty.IntersectWith(&VisibleContentRegion());
fDrawingEngine->Unlock();
}
fTopLayer->Draw(fDrawingEngine, &dirty,
&fContentRegion, true);
#endif
} else {
fprintf(stderr, "WindowLayer::BeginUpdate() - no update requested!\n");
-13
View File
@@ -31,19 +31,6 @@ class WindowLayer;
// TODO: move this into a proper place
#define AS_REDRAW 'rdrw'
// if the background clearing is delayed until
// the client draws the view, we have less flickering
// when contents have to be redrawn because of resizing
// a window or because the client invalidates parts.
// when redrawing something that has been exposed from underneath
// other windows, the other window will be seen longer at
// its previous position though if the exposed parts are not
// cleared right away. maybe there ought to be a flag in
// the update session, which tells us the cause of the update
#define DELAYED_BACKGROUND_CLEARING 0
class WindowLayer {
public:
WindowLayer(const BRect& frame,
+20 -24
View File
@@ -758,34 +758,30 @@ DrawingEngine::FillRegion(BRegion& r, const RGBColor& color)
// NOTE: Write locking because we might use HW acceleration.
// This needs to be investigated, I'm doing this because of
// gut feeling.
// NOTE: region expected to be already clipped correctly!!
if (WriteLock()) {
BRect clipped = fPainter->ClipRect(r.Frame());
if (clipped.IsValid()) {
fGraphicsCard->HideSoftwareCursor(clipped);
fGraphicsCard->HideSoftwareCursor(r.Frame());
bool doInSoftware = true;
// try hardware optimized version first
if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) != 0) {
// NOTE: region expected to be already clipped correctly
// r.IntersectWith(fPainter->ClippingRegion());
fGraphicsCard->FillRegion(r, color);
doInSoftware = false;
}
if (doInSoftware) {
int32 count = r.CountRects();
for (int32 i = 0; i < count; i++) {
fPainter->FillRect(r.RectAt(i), color.GetColor32());
}
BRect touched = r.Frame();
fGraphicsCard->Invalidate(touched);
}
fGraphicsCard->ShowSoftwareCursor();
bool doInSoftware = true;
// try hardware optimized version first
if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) != 0) {
fGraphicsCard->FillRegion(r, color);
doInSoftware = false;
}
if (doInSoftware) {
int32 count = r.CountRects();
for (int32 i = 0; i < count; i++) {
fPainter->FillRectNoClipping(r.RectAt(i), color.GetColor32());
}
BRect touched = r.Frame();
fGraphicsCard->Invalidate(touched);
}
fGraphicsCard->ShowSoftwareCursor();
WriteUnlock();
}
}
@@ -738,6 +738,38 @@ Painter::FillRect(const BRect& r, const rgb_color& c) const
}
}
// FillRectNoClipping
void
Painter::FillRectNoClipping(const BRect& r, const rgb_color& c) const
{
if (fBuffer) {
int32 left = (int32)r.left;
int32 y = (int32)r.top;
int32 right = (int32)r.right;
int32 bottom = (int32)r.bottom;
uint8* dst = fBuffer->row(y);
uint32 bpr = fBuffer->stride();
// get a 32 bit pixel ready with the color
pixel32 color;
color.data8[0] = c.blue;
color.data8[1] = c.green;
color.data8[2] = c.red;
color.data8[3] = c.alpha;
dst += left * 4;
for (; y <= bottom; y++) {
uint32* handle = (uint32*)dst;
for (int32 x = left; x <= right; x++) {
*handle++ = color.data32;
}
dst += bpr;
}
}
}
// StrokeRoundRect
BRect
Painter::StrokeRoundRect(const BRect& r, float xRadius, float yRadius) const
@@ -136,6 +136,9 @@ class Painter {
// fills a solid rect with color c, no blending
void FillRect( const BRect& r,
const rgb_color& c) const;
// fills a solid rect with color c, no blending, no clipping
void FillRectNoClipping(const BRect& r,
const rgb_color& c) const;
// round rects
BRect StrokeRoundRect(const BRect& r,