diff --git a/src/servers/app/Angle.cpp b/src/servers/app/Angle.cpp index dc69327dfa..04cb17968a 100644 --- a/src/servers/app/Angle.cpp +++ b/src/servers/app/Angle.cpp @@ -31,10 +31,10 @@ #define ANGLE_PI 3.14159265358979323846 #endif -bool sTablesInitialized = false; -float sSinTable[360]; -float sCosTable[360]; -float sTanTable[360]; +static bool sTablesInitialized = false; +static float sSinTable[360]; +static float sCosTable[360]; +static float sTanTable[360]; /*! \brief Constructor diff --git a/src/servers/app/DecorManager.cpp b/src/servers/app/DecorManager.cpp index dd735689c6..623a9fe8ae 100644 --- a/src/servers/app/DecorManager.cpp +++ b/src/servers/app/DecorManager.cpp @@ -92,7 +92,7 @@ DecorInfo::Instantiate(Desktop* desktop, BRect rect, const char *title, desktop->UnlockSingleWindow(); - decorator->SetDriver(desktop->GetDrawingEngine()); + decorator->SetDrawingEngine(desktop->GetDrawingEngine()); decorator->SetTitle(title); return decorator; diff --git a/src/servers/app/Decorator.cpp b/src/servers/app/Decorator.cpp index 0d16dd8258..d4db393884 100644 --- a/src/servers/app/Decorator.cpp +++ b/src/servers/app/Decorator.cpp @@ -30,19 +30,19 @@ Decorator::Decorator(DesktopSettings& settings, BRect rect, window_look look, uint32 flags) : - _driver(NULL), + fDrawingEngine(NULL), fDrawState(), fLook(look), fFlags(flags), - _zoomrect(), - _closerect(), - _minimizerect(), - _tabrect(), - _frame(rect), - _resizerect(), - _borderrect(), + fZoomRect(), + fCloseRect(), + fMinimizeRect(), + fTabRect(), + fFrame(rect), + fResizeRect(), + fBorderRect(), fClosePressed(false), fZoomPressed(false), @@ -68,12 +68,12 @@ Decorator::~Decorator() \param driver A valid DrawingEngine object */ void -Decorator::SetDriver(DrawingEngine *driver) +Decorator::SetDrawingEngine(DrawingEngine* engine) { - _driver = driver; + fDrawingEngine = engine; // lots of subclasses will depend on the driver for text support, so call // _DoLayout() after we have it - if (_driver) { + if (fDrawingEngine) { _DoLayout(); } } @@ -227,7 +227,7 @@ Decorator::Title() const BRect Decorator::BorderRect() const { - return _borderrect; + return fBorderRect; } @@ -238,7 +238,7 @@ Decorator::BorderRect() const BRect Decorator::TabRect() const { - return _tabrect; + return fTabRect; } /*! @@ -373,14 +373,14 @@ Decorator::MoveBy(float x, float y) void Decorator::MoveBy(BPoint pt) { - _zoomrect.OffsetBy(pt); - _closerect.OffsetBy(pt); - _minimizerect.OffsetBy(pt); - _minimizerect.OffsetBy(pt); - _tabrect.OffsetBy(pt); - _frame.OffsetBy(pt); - _resizerect.OffsetBy(pt); - _borderrect.OffsetBy(pt); + fZoomRect.OffsetBy(pt); + fCloseRect.OffsetBy(pt); + fMinimizeRect.OffsetBy(pt); + fMinimizeRect.OffsetBy(pt); + fTabRect.OffsetBy(pt); + fFrame.OffsetBy(pt); + fResizeRect.OffsetBy(pt); + fBorderRect.OffsetBy(pt); } /*! @@ -389,7 +389,7 @@ Decorator::MoveBy(BPoint pt) \param dy y offset This is a required function for subclasses to implement - the default does nothing. - Note that window resize flags should be followed and _frame should be resized + Note that window resize flags should be followed and fFrame should be resized accordingly. It would also be a wise idea to ensure that the window's rectangles are not inverted. */ @@ -423,62 +423,62 @@ Decorator::GetSettings(BMessage* settings) const void Decorator::Draw(BRect r) { - _DrawFrame(r & _frame); - _DrawTab(r & _tabrect); + _DrawFrame(r & fFrame); + _DrawTab(r & fTabRect); } //! Forces a complete decorator update void Decorator::Draw() { - _DrawFrame(_frame); - _DrawTab(_tabrect); + _DrawFrame(fFrame); + _DrawTab(fTabRect); } //! Draws the close button void Decorator::DrawClose() { - _DrawClose(_closerect); + _DrawClose(fCloseRect); } //! draws the frame void Decorator::DrawFrame() { - _DrawFrame(_frame); + _DrawFrame(fFrame); } //! draws the minimize button void Decorator::DrawMinimize(void) { - _DrawTab(_minimizerect); + _DrawTab(fMinimizeRect); } //! draws the tab, title, and buttons void Decorator::DrawTab() { - _DrawTab(_tabrect); - _DrawZoom(_zoomrect); - _DrawMinimize(_minimizerect); - _DrawTitle(_tabrect); - _DrawClose(_closerect); + _DrawTab(fTabRect); + _DrawZoom(fZoomRect); + _DrawMinimize(fMinimizeRect); + _DrawTitle(fTabRect); + _DrawClose(fCloseRect); } // draws the title void Decorator::DrawTitle() { - _DrawTitle(_tabrect); + _DrawTitle(fTabRect); } //! draws the zoom button void Decorator::DrawZoom(void) { - _DrawZoom(_zoomrect); + _DrawZoom(fZoomRect); } @@ -501,16 +501,16 @@ Decorator::_ClipTitle(float width) { // TODO: eventually, use ServerFont::TruncateString() // when it exists (if it doesn't already) - if (_driver) { + if (fDrawingEngine) { int32 strlength = fTitle.CountChars(); - float pixwidth=_driver->StringWidth(fTitle.String(),strlength,&fDrawState); + float pixwidth=fDrawingEngine->StringWidth(fTitle.String(),strlength,&fDrawState); while (strlength >= 0) { if (pixwidth < width) return strlength; strlength--; - pixwidth=_driver->StringWidth(fTitle.String(), strlength, &fDrawState); + pixwidth=fDrawingEngine->StringWidth(fTitle.String(), strlength, &fDrawState); } } return 0; diff --git a/src/servers/app/Decorator.h b/src/servers/app/Decorator.h index 92481fd366..d33a988ff7 100644 --- a/src/servers/app/Decorator.h +++ b/src/servers/app/Decorator.h @@ -50,7 +50,9 @@ class Decorator { window_look look, uint32 flags); virtual ~Decorator(); - void SetDriver(DrawingEngine *driver); + void SetDrawingEngine(DrawingEngine *driver); + inline DrawingEngine* GetDrawingEngine() const + { return fDrawingEngine; } void SetFont(ServerFont *font); virtual void SetLook(DesktopSettings& settings, @@ -68,7 +70,7 @@ class Decorator { const char* Title() const; - // we need to know its border(frame). WinBorder's _frame rect + // we need to know its border(frame). WinBorder's fFrame rect // must expand to include Decorator borders. Otherwise we can't // draw the border. We also add TabRect because I feel we'll need it BRect BorderRect() const; @@ -138,19 +140,19 @@ class Decorator { virtual void _SetFocus(); - DrawingEngine* _driver; + DrawingEngine* fDrawingEngine; DrawState fDrawState; window_look fLook; uint32 fFlags; - BRect _zoomrect; - BRect _closerect; - BRect _minimizerect; - BRect _tabrect; - BRect _frame; - BRect _resizerect; - BRect _borderrect; + BRect fZoomRect; + BRect fCloseRect; + BRect fMinimizeRect; + BRect fTabRect; + BRect fFrame; + BRect fResizeRect; + BRect fBorderRect; private: bool fClosePressed; diff --git a/src/servers/app/DefaultDecorator.cpp b/src/servers/app/DefaultDecorator.cpp index 165b59c0a1..517243206a 100644 --- a/src/servers/app/DefaultDecorator.cpp +++ b/src/servers/app/DefaultDecorator.cpp @@ -207,12 +207,12 @@ DefaultDecorator::MoveBy(BPoint pt) { STRACE(("DefaultDecorator: Move By (%.1f, %.1f)\n",pt.x,pt.y)); // Move all internal rectangles the appropriate amount - _frame.OffsetBy(pt); - _closerect.OffsetBy(pt); - _tabrect.OffsetBy(pt); - _resizerect.OffsetBy(pt); - _zoomrect.OffsetBy(pt); - _borderrect.OffsetBy(pt); + fFrame.OffsetBy(pt); + fCloseRect.OffsetBy(pt); + fTabRect.OffsetBy(pt); + fResizeRect.OffsetBy(pt); + fZoomRect.OffsetBy(pt); + fBorderRect.OffsetBy(pt); fLeftBorder.OffsetBy(pt); fRightBorder.OffsetBy(pt); @@ -226,15 +226,15 @@ DefaultDecorator::ResizeBy(BPoint pt, BRegion* dirty) { STRACE(("DefaultDecorator: Resize By (%.1f, %.1f)\n", pt.x, pt.y)); // Move all internal rectangles the appropriate amount - _frame.right += pt.x; - _frame.bottom += pt.y; + fFrame.right += pt.x; + fFrame.bottom += pt.y; // handle invalidation of resize rect if (dirty && !(fFlags & B_NOT_RESIZABLE)) { BRect realResizeRect; switch (fLook) { case B_DOCUMENT_WINDOW_LOOK: - realResizeRect = _resizerect; + realResizeRect = fResizeRect; // resize rect at old location dirty->Include(realResizeRect); realResizeRect.OffsetBy(pt); @@ -266,10 +266,10 @@ DefaultDecorator::ResizeBy(BPoint pt, BRegion* dirty) } } - _resizerect.OffsetBy(pt); + fResizeRect.OffsetBy(pt); - _borderrect.right += pt.x; - _borderrect.bottom += pt.y; + fBorderRect.right += pt.x; + fBorderRect.bottom += pt.y; fLeftBorder.bottom += pt.y; fTopBorder.right += pt.x; @@ -307,8 +307,8 @@ DefaultDecorator::ResizeBy(BPoint pt, BRegion* dirty) } // resize tab and layout tab items - if (_tabrect.IsValid()) { - BRect oldTabRect(_tabrect); + if (fTabRect.IsValid()) { + BRect oldTabRect(fTabRect); float tabSize; float maxLocation; @@ -325,30 +325,30 @@ DefaultDecorator::ResizeBy(BPoint pt, BRegion* dirty) float delta = tabOffset - fTabOffset; fTabOffset = (uint32)tabOffset; if (fLook != kLeftTitledWindowLook) - _tabrect.OffsetBy(delta, 0.0); + fTabRect.OffsetBy(delta, 0.0); else - _tabrect.OffsetBy(0.0, delta); + fTabRect.OffsetBy(0.0, delta); if (tabSize < fMinTabSize) tabSize = fMinTabSize; if (tabSize > fMaxTabSize) tabSize = fMaxTabSize; - if (fLook != kLeftTitledWindowLook && tabSize != _tabrect.Width()) { - _tabrect.right = _tabrect.left + tabSize; - } else if (fLook == kLeftTitledWindowLook && tabSize != _tabrect.Height()) { - _tabrect.bottom = _tabrect.top + tabSize; + if (fLook != kLeftTitledWindowLook && tabSize != fTabRect.Width()) { + fTabRect.right = fTabRect.left + tabSize; + } else if (fLook == kLeftTitledWindowLook && tabSize != fTabRect.Height()) { + fTabRect.bottom = fTabRect.top + tabSize; } - if (oldTabRect != _tabrect) { - _LayoutTabItems(_tabrect); + if (oldTabRect != fTabRect) { + _LayoutTabItems(fTabRect); if (dirty) { // NOTE: the tab rect becoming smaller only would // handled be the Desktop anyways, so it is sufficient // to include it into the dirty region in it's // final state - BRect redraw(_tabrect); + BRect redraw(fTabRect); if (delta != 0.0) { redraw = redraw | oldTabRect; if (fLook != kLeftTitledWindowLook) @@ -367,13 +367,13 @@ bool DefaultDecorator::SetTabLocation(float location, BRegion* updateRegion) { STRACE(("DefaultDecorator: Set Tab Location(%.1f)\n", location)); - if (!_tabrect.IsValid()) + if (!fTabRect.IsValid()) return false; if (location < 0) location = 0; - float maxLocation = fRightBorder.right - fLeftBorder.left - _tabrect.Width(); + float maxLocation = fRightBorder.right - fLeftBorder.left - fTabRect.Width(); if (location > maxLocation) location = maxLocation; @@ -382,18 +382,18 @@ DefaultDecorator::SetTabLocation(float location, BRegion* updateRegion) return false; // redraw old rect (1 pix on the border also must be updated) - BRect trect(_tabrect); + BRect trect(fTabRect); trect.bottom++; updateRegion->Include(trect); - _tabrect.OffsetBy(delta, 0); + fTabRect.OffsetBy(delta, 0); fTabOffset = (int32)location; - _LayoutTabItems(_tabrect); + _LayoutTabItems(fTabRect); fTabLocation = maxLocation > 0.0 ? fTabOffset / maxLocation : 0.0; // redraw new rect as well - trect = _tabrect; + trect = fTabRect; trect.bottom++; updateRegion->Include(trect); return true; @@ -414,7 +414,7 @@ DefaultDecorator::SetSettings(const BMessage& settings, BRegion* updateRegion) bool DefaultDecorator::GetSettings(BMessage* settings) const { - if (!_tabrect.IsValid()) + if (!fTabRect.IsValid()) return false; return settings->AddFloat("tab location", (float)fTabOffset) == B_OK; @@ -445,7 +445,7 @@ DefaultDecorator::Draw() // things _DrawFrame(BRect(fTopBorder.LeftTop(), fBottomBorder.RightBottom())); - _DrawTab(_tabrect); + _DrawTab(fTabRect); } // GetSizeLimits @@ -453,10 +453,10 @@ void DefaultDecorator::GetSizeLimits(int32* minWidth, int32* minHeight, int32* maxWidth, int32* maxHeight) const { - if (_tabrect.IsValid()) + if (fTabRect.IsValid()) *minWidth = (int32)roundf(max_c(*minWidth, fMinTabSize - 2 * fBorderWidth)); - if (_resizerect.IsValid()) - *minHeight = (int32)roundf(max_c(*minHeight, _resizerect.Height() - fBorderWidth)); + if (fResizeRect.IsValid()) + *minHeight = (int32)roundf(max_c(*minHeight, fResizeRect.Height() - fBorderWidth)); } // GetFootprint @@ -483,12 +483,12 @@ DefaultDecorator::GetFootprint(BRegion *region) if (fLook == B_BORDERED_WINDOW_LOOK) return; - region->Include(_tabrect); + region->Include(fTabRect); if (fLook == B_DOCUMENT_WINDOW_LOOK) { // include the rectangular resize knob on the bottom right - region->Include(BRect(_frame.right - 13.0f, _frame.bottom - 13.0f, - _frame.right, _frame.bottom)); + region->Include(BRect(fFrame.right - 13.0f, fFrame.bottom - 13.0f, + fFrame.right, fFrame.bottom)); } } @@ -511,19 +511,19 @@ DefaultDecorator::Clicked(BPoint pt, int32 buttons, int32 modifiers) // In checking for hit test stuff, we start with the smallest rectangles the user might // be clicking on and gradually work our way out into larger rectangles. - if (!(fFlags & B_NOT_CLOSABLE) && _closerect.Contains(pt)) + if (!(fFlags & B_NOT_CLOSABLE) && fCloseRect.Contains(pt)) return DEC_CLOSE; - if (!(fFlags & B_NOT_ZOOMABLE) && _zoomrect.Contains(pt)) + if (!(fFlags & B_NOT_ZOOMABLE) && fZoomRect.Contains(pt)) return DEC_ZOOM; - if (fLook == B_DOCUMENT_WINDOW_LOOK && _resizerect.Contains(pt)) + if (fLook == B_DOCUMENT_WINDOW_LOOK && fResizeRect.Contains(pt)) return DEC_RESIZE; bool clicked = false; // Clicking in the tab? - if (_tabrect.Contains(pt)) { + if (fTabRect.Contains(pt)) { // tab sliding in any case if either shift key is held down // except sliding up-down by moving mouse left-right would look strange if ((modifiers & B_SHIFT_KEY) && (fLook != kLeftTitledWindowLook)) @@ -610,26 +610,26 @@ DefaultDecorator::_DoLayout() fDrawState.Font().GetHeight(fontHeight); if (fLook != kLeftTitledWindowLook) { - _tabrect.Set(_frame.left - fBorderWidth, - _frame.top - fBorderWidth - ceilf(fontHeight.ascent + fontHeight.descent + 7.0), - ((_frame.right - _frame.left) < 35.0 ? - _frame.left + 35.0 : _frame.right) + fBorderWidth, - _frame.top - fBorderWidth); + fTabRect.Set(fFrame.left - fBorderWidth, + fFrame.top - fBorderWidth - ceilf(fontHeight.ascent + fontHeight.descent + 7.0), + ((fFrame.right - fFrame.left) < 35.0 ? + fFrame.left + 35.0 : fFrame.right) + fBorderWidth, + fFrame.top - fBorderWidth); } else { - _tabrect.Set(_frame.left - fBorderWidth - ceilf(fontHeight.ascent + fontHeight.descent + 5.0), - _frame.top - fBorderWidth, _frame.left - fBorderWidth, - _frame.bottom + fBorderWidth); + fTabRect.Set(fFrame.left - fBorderWidth - ceilf(fontHeight.ascent + fontHeight.descent + 5.0), + fFrame.top - fBorderWidth, fFrame.left - fBorderWidth, + fFrame.bottom + fBorderWidth); } // format tab rect for a floating window - make the rect smaller if (fLook == B_FLOATING_WINDOW_LOOK) { - _tabrect.InsetBy(0, 2); - _tabrect.OffsetBy(0, 2); + fTabRect.InsetBy(0, 2); + fTabRect.OffsetBy(0, 2); } float offset; float size; - _GetButtonSizeAndOffset(_tabrect, &offset, &size); + _GetButtonSizeAndOffset(fTabRect, &offset, &size); // fMinTabSize contains just the room for the buttons fMinTabSize = 4.0 + fTextOffset; @@ -639,13 +639,13 @@ DefaultDecorator::_DoLayout() fMinTabSize += offset + size; // fMaxTabSize contains fMinWidth + the width required for the title - fMaxTabSize = _driver ? ceilf(_driver->StringWidth(Title(), strlen(Title()), + fMaxTabSize = fDrawingEngine ? ceilf(fDrawingEngine->StringWidth(Title(), strlen(Title()), &fDrawState)) : 0.0; if (fMaxTabSize > 0.0) fMaxTabSize += fTextOffset; fMaxTabSize += fMinTabSize; - float tabSize = fLook != kLeftTitledWindowLook ? _frame.Width() : _frame.Height(); + float tabSize = fLook != kLeftTitledWindowLook ? fFrame.Width() : fFrame.Height(); if (tabSize < fMinTabSize) tabSize = fMinTabSize; if (tabSize > fMaxTabSize) @@ -653,33 +653,33 @@ DefaultDecorator::_DoLayout() // layout buttons and truncate text if (fLook != kLeftTitledWindowLook) - _tabrect.right = _tabrect.left + tabSize; + fTabRect.right = fTabRect.left + tabSize; else - _tabrect.bottom = _tabrect.top + tabSize; + fTabRect.bottom = fTabRect.top + tabSize; } else { // no tab fMinTabSize = 0.0; fMaxTabSize = 0.0; - _tabrect.Set(0.0, 0.0, -1.0, -1.0); - _closerect.Set(0.0, 0.0, -1.0, -1.0); - _zoomrect.Set(0.0, 0.0, -1.0, -1.0); + fTabRect.Set(0.0, 0.0, -1.0, -1.0); + fCloseRect.Set(0.0, 0.0, -1.0, -1.0); + fZoomRect.Set(0.0, 0.0, -1.0, -1.0); } // calculate left/top/right/bottom borders if (fBorderWidth > 0) { // NOTE: no overlapping, the left and right border rects // don't include the corners! - fLeftBorder.Set(_frame.left - fBorderWidth, _frame.top, - _frame.left - 1, _frame.bottom); + fLeftBorder.Set(fFrame.left - fBorderWidth, fFrame.top, + fFrame.left - 1, fFrame.bottom); - fRightBorder.Set(_frame.right + 1, _frame.top , - _frame.right + fBorderWidth, _frame.bottom); + fRightBorder.Set(fFrame.right + 1, fFrame.top , + fFrame.right + fBorderWidth, fFrame.bottom); - fTopBorder.Set(_frame.left - fBorderWidth, _frame.top - fBorderWidth, - _frame.right + fBorderWidth, _frame.top - 1); + fTopBorder.Set(fFrame.left - fBorderWidth, fFrame.top - fBorderWidth, + fFrame.right + fBorderWidth, fFrame.top - 1); - fBottomBorder.Set(_frame.left - fBorderWidth, _frame.bottom + 1, - _frame.right + fBorderWidth, _frame.bottom + fBorderWidth); + fBottomBorder.Set(fFrame.left - fBorderWidth, fFrame.bottom + 1, + fFrame.right + fBorderWidth, fFrame.bottom + fBorderWidth); } else { // no border fLeftBorder.Set(0.0, 0.0, -1.0, -1.0); @@ -689,21 +689,21 @@ DefaultDecorator::_DoLayout() } // calculate resize rect - _resizerect.Set(fBottomBorder.right - 18.0, fBottomBorder.bottom - 18.0, + fResizeRect.Set(fBottomBorder.right - 18.0, fBottomBorder.bottom - 18.0, fBottomBorder.right, fBottomBorder.bottom); if (hasTab) { // make sure fTabOffset is within limits and apply it to - // the _tabrect + // the fTabRect if (fTabOffset < 0) fTabOffset = 0; if (fTabLocation != 0.0 - && fTabOffset > (fRightBorder.right - fLeftBorder.left - _tabrect.Width())) - fTabOffset = uint32(fRightBorder.right - fLeftBorder.left - _tabrect.Width()); - _tabrect.OffsetBy(fTabOffset, 0); + && fTabOffset > (fRightBorder.right - fLeftBorder.left - fTabRect.Width())) + fTabOffset = uint32(fRightBorder.right - fLeftBorder.left - fTabRect.Width()); + fTabRect.OffsetBy(fTabOffset, 0); // finally, layout the buttons and text within the tab rect - _LayoutTabItems(_tabrect); + _LayoutTabItems(fTabRect); } } @@ -733,21 +733,21 @@ DefaultDecorator::_DrawFrame(BRect invalid) // top if (invalid.Intersects(fTopBorder)) { for (int8 i = 0; i < 5; i++) { - _driver->StrokeLine(BPoint(r.left + i, r.top + i), + fDrawingEngine->StrokeLine(BPoint(r.left + i, r.top + i), BPoint(r.right - i, r.top + i), fFrameColors[i]); } - if (_tabrect.IsValid()) { + if (fTabRect.IsValid()) { // grey along the bottom of the tab (overwrites "white" from frame) - _driver->StrokeLine(BPoint(_tabrect.left + 2, _tabrect.bottom + 1), - BPoint(_tabrect.right - 2, _tabrect.bottom + 1), + fDrawingEngine->StrokeLine(BPoint(fTabRect.left + 2, fTabRect.bottom + 1), + BPoint(fTabRect.right - 2, fTabRect.bottom + 1), fFrameColors[2]); } } // left if (invalid.Intersects(fLeftBorder.InsetByCopy(0, -fBorderWidth))) { for (int8 i = 0; i < 5; i++) { - _driver->StrokeLine(BPoint(r.left + i, r.top + i), + fDrawingEngine->StrokeLine(BPoint(r.left + i, r.top + i), BPoint(r.left + i, r.bottom - i), fFrameColors[i]); } @@ -755,7 +755,7 @@ DefaultDecorator::_DrawFrame(BRect invalid) // bottom if (invalid.Intersects(fBottomBorder)) { for (int8 i = 0; i < 5; i++) { - _driver->StrokeLine(BPoint(r.left + i, r.bottom - i), + fDrawingEngine->StrokeLine(BPoint(r.left + i, r.bottom - i), BPoint(r.right - i, r.bottom - i), fFrameColors[(4 - i) == 4 ? 5 : (4 - i)]); } @@ -763,7 +763,7 @@ DefaultDecorator::_DrawFrame(BRect invalid) // right if (invalid.Intersects(fRightBorder.InsetByCopy(0, -fBorderWidth))) { for (int8 i = 0; i < 5; i++) { - _driver->StrokeLine(BPoint(r.right - i, r.top + i), + fDrawingEngine->StrokeLine(BPoint(r.right - i, r.top + i), BPoint(r.right - i, r.bottom - i), fFrameColors[(4 - i) == 4 ? 5 : (4 - i)]); } @@ -777,35 +777,35 @@ DefaultDecorator::_DrawFrame(BRect invalid) // top if (invalid.Intersects(fTopBorder)) { for (int8 i = 0; i < 3; i++) { - _driver->StrokeLine(BPoint(r.left + i, r.top + i), + fDrawingEngine->StrokeLine(BPoint(r.left + i, r.top + i), BPoint(r.right - i, r.top + i), fFrameColors[i * 2]); } - if (_tabrect.IsValid() && fLook != kLeftTitledWindowLook) { + if (fTabRect.IsValid() && fLook != kLeftTitledWindowLook) { // grey along the bottom of the tab (overwrites "white" from frame) - _driver->StrokeLine(BPoint(_tabrect.left + 2, _tabrect.bottom + 1), - BPoint(_tabrect.right - 2, _tabrect.bottom + 1), + fDrawingEngine->StrokeLine(BPoint(fTabRect.left + 2, fTabRect.bottom + 1), + BPoint(fTabRect.right - 2, fTabRect.bottom + 1), fFrameColors[2]); } } // left if (invalid.Intersects(fLeftBorder.InsetByCopy(0, -fBorderWidth))) { for (int8 i = 0; i < 3; i++) { - _driver->StrokeLine(BPoint(r.left + i, r.top + i), + fDrawingEngine->StrokeLine(BPoint(r.left + i, r.top + i), BPoint(r.left + i, r.bottom - i), fFrameColors[i * 2]); } - if (fLook == kLeftTitledWindowLook && _tabrect.IsValid()) { + if (fLook == kLeftTitledWindowLook && fTabRect.IsValid()) { // grey along the right side of the tab (overwrites "white" from frame) - _driver->StrokeLine(BPoint(_tabrect.right + 1, _tabrect.top + 2), - BPoint(_tabrect.right + 1, _tabrect.bottom - 2), + fDrawingEngine->StrokeLine(BPoint(fTabRect.right + 1, fTabRect.top + 2), + BPoint(fTabRect.right + 1, fTabRect.bottom - 2), fFrameColors[2]); } } // bottom if (invalid.Intersects(fBottomBorder)) { for (int8 i = 0; i < 3; i++) { - _driver->StrokeLine(BPoint(r.left + i, r.bottom - i), + fDrawingEngine->StrokeLine(BPoint(r.left + i, r.bottom - i), BPoint(r.right - i, r.bottom - i), fFrameColors[(2 - i) == 2 ? 5 : (2 - i) * 2]); } @@ -813,7 +813,7 @@ DefaultDecorator::_DrawFrame(BRect invalid) // right if (invalid.Intersects(fRightBorder.InsetByCopy(0, -fBorderWidth))) { for (int8 i = 0; i < 3; i++) { - _driver->StrokeLine(BPoint(r.right - i, r.top + i), + fDrawingEngine->StrokeLine(BPoint(r.right - i, r.top + i), BPoint(r.right - i, r.bottom - i), fFrameColors[(2 - i) == 2 ? 5 : (2 - i) * 2]); } @@ -822,7 +822,7 @@ DefaultDecorator::_DrawFrame(BRect invalid) } case B_BORDERED_WINDOW_LOOK: - _driver->StrokeRect(r, fFrameColors[5]); + fDrawingEngine->StrokeRect(r, fFrameColors[5]); break; default: @@ -832,7 +832,7 @@ DefaultDecorator::_DrawFrame(BRect invalid) // Draw the resize thumb if we're supposed to if (!(fFlags & B_NOT_RESIZABLE)) { - r = _resizerect; + r = fResizeRect; switch (fLook) { case B_DOCUMENT_WINDOW_LOOK: @@ -843,14 +843,14 @@ DefaultDecorator::_DrawFrame(BRect invalid) float x = r.right - 3; float y = r.bottom - 3; - _driver->FillRect(BRect(x - 13, y - 13, x, y), fFrameColors[2]); - _driver->StrokeLine(BPoint(x - 15, y - 15), BPoint(x - 15, y - 2), + fDrawingEngine->FillRect(BRect(x - 13, y - 13, x, y), fFrameColors[2]); + fDrawingEngine->StrokeLine(BPoint(x - 15, y - 15), BPoint(x - 15, y - 2), fFrameColors[0]); - _driver->StrokeLine(BPoint(x - 14, y - 14), BPoint(x - 14, y - 1), + fDrawingEngine->StrokeLine(BPoint(x - 14, y - 14), BPoint(x - 14, y - 1), fFrameColors[1]); - _driver->StrokeLine(BPoint(x - 15, y - 15), BPoint(x - 2, y - 15), + fDrawingEngine->StrokeLine(BPoint(x - 15, y - 15), BPoint(x - 2, y - 15), fFrameColors[0]); - _driver->StrokeLine(BPoint(x - 14, y - 14), BPoint(x - 1, y - 14), + fDrawingEngine->StrokeLine(BPoint(x - 14, y - 14), BPoint(x - 1, y - 14), fFrameColors[1]); if (!IsFocus()) @@ -860,8 +860,8 @@ DefaultDecorator::_DrawFrame(BRect invalid) for (int8 j = 1; j <= i; j++) { BPoint pt1(x - (3 * j) + 1, y - (3 * (5 - i)) + 1); BPoint pt2(x - (3 * j) + 2, y - (3 * (5 - i)) + 2); - _driver->StrokePoint(pt1, fFrameColors[0]); - _driver->StrokePoint(pt2, fFrameColors[1]); + fDrawingEngine->StrokePoint(pt1, fFrameColors[0]); + fDrawingEngine->StrokePoint(pt2, fFrameColors[1]); } } break; @@ -877,10 +877,10 @@ DefaultDecorator::_DrawFrame(BRect invalid) fBottomBorder.bottom - 1))) break; - _driver->StrokeLine(BPoint(fRightBorder.left, fBottomBorder.bottom - 22), + fDrawingEngine->StrokeLine(BPoint(fRightBorder.left, fBottomBorder.bottom - 22), BPoint(fRightBorder.right - 1, fBottomBorder.bottom - 22), fFrameColors[0]); - _driver->StrokeLine(BPoint(fRightBorder.right - 22, fBottomBorder.top), + fDrawingEngine->StrokeLine(BPoint(fRightBorder.right - 22, fBottomBorder.top), BPoint(fRightBorder.right - 22, fBottomBorder.bottom - 1), fFrameColors[0]); break; @@ -901,7 +901,7 @@ DefaultDecorator::_DrawTab(BRect invalid) invalid.left, invalid.top, invalid.right, invalid.bottom)); // If a window has a tab, this will draw it and any buttons which are // in it. - if (!_tabrect.IsValid() || !invalid.Intersects(_tabrect)) + if (!fTabRect.IsValid() || !invalid.Intersects(fTabRect)) return; // TODO: cache these @@ -911,45 +911,45 @@ DefaultDecorator::_DrawTab(BRect invalid) B_DARKEN_2_TINT)); // outer frame - _driver->StrokeLine(_tabrect.LeftTop(), _tabrect.LeftBottom(), fFrameColors[0]); - _driver->StrokeLine(_tabrect.LeftTop(), _tabrect.RightTop(), fFrameColors[0]); + fDrawingEngine->StrokeLine(fTabRect.LeftTop(), fTabRect.LeftBottom(), fFrameColors[0]); + fDrawingEngine->StrokeLine(fTabRect.LeftTop(), fTabRect.RightTop(), fFrameColors[0]); if (fLook != kLeftTitledWindowLook) - _driver->StrokeLine(_tabrect.RightTop(),_tabrect.RightBottom(), fFrameColors[5]); + fDrawingEngine->StrokeLine(fTabRect.RightTop(),fTabRect.RightBottom(), fFrameColors[5]); else - _driver->StrokeLine(_tabrect.LeftBottom(),_tabrect.RightBottom(), fFrameColors[5]); + fDrawingEngine->StrokeLine(fTabRect.LeftBottom(),fTabRect.RightBottom(), fFrameColors[5]); // bevel - _driver->StrokeLine(BPoint(_tabrect.left + 1, _tabrect.top + 1), - BPoint(_tabrect.left + 1, _tabrect.bottom - (fLook == kLeftTitledWindowLook ? 1 : 0)), + fDrawingEngine->StrokeLine(BPoint(fTabRect.left + 1, fTabRect.top + 1), + BPoint(fTabRect.left + 1, fTabRect.bottom - (fLook == kLeftTitledWindowLook ? 1 : 0)), tabColorLight); - _driver->StrokeLine(BPoint(_tabrect.left + 1, _tabrect.top + 1), - BPoint(_tabrect.right - (fLook == kLeftTitledWindowLook ? 0 : 1), _tabrect.top + 1), + fDrawingEngine->StrokeLine(BPoint(fTabRect.left + 1, fTabRect.top + 1), + BPoint(fTabRect.right - (fLook == kLeftTitledWindowLook ? 0 : 1), fTabRect.top + 1), tabColorLight); if (fLook != kLeftTitledWindowLook) { - _driver->StrokeLine(BPoint(_tabrect.right - 1, _tabrect.top + 2), - BPoint(_tabrect.right - 1, _tabrect.bottom), tabColorShadow); + fDrawingEngine->StrokeLine(BPoint(fTabRect.right - 1, fTabRect.top + 2), + BPoint(fTabRect.right - 1, fTabRect.bottom), tabColorShadow); } else { - _driver->StrokeLine(BPoint(_tabrect.left + 2, _tabrect.bottom - 1), - BPoint(_tabrect.right, _tabrect.bottom - 1), tabColorShadow); + fDrawingEngine->StrokeLine(BPoint(fTabRect.left + 2, fTabRect.bottom - 1), + BPoint(fTabRect.right, fTabRect.bottom - 1), tabColorShadow); } // fill if (fLook != kLeftTitledWindowLook) { - _driver->FillRect(BRect(_tabrect.left + 2, _tabrect.top + 2, - _tabrect.right - 2, _tabrect.bottom), fTabColor); + fDrawingEngine->FillRect(BRect(fTabRect.left + 2, fTabRect.top + 2, + fTabRect.right - 2, fTabRect.bottom), fTabColor); } else { - _driver->FillRect(BRect(_tabrect.left + 2, _tabrect.top + 2, - _tabrect.right, _tabrect.bottom - 2), fTabColor); + fDrawingEngine->FillRect(BRect(fTabRect.left + 2, fTabRect.top + 2, + fTabRect.right, fTabRect.bottom - 2), fTabColor); } - _DrawTitle(_tabrect); + _DrawTitle(fTabRect); // Draw the buttons if we're supposed to - if (!(fFlags & B_NOT_CLOSABLE) && invalid.Intersects(_closerect)) - _DrawClose(_closerect); - if (!(fFlags & B_NOT_ZOOMABLE) && invalid.Intersects(_zoomrect)) - _DrawZoom(_zoomrect); + if (!(fFlags & B_NOT_CLOSABLE) && invalid.Intersects(fCloseRect)) + _DrawClose(fCloseRect); + if (!(fFlags & B_NOT_ZOOMABLE) && invalid.Intersects(fZoomRect)) + _DrawZoom(fZoomRect); } // _DrawClose @@ -976,18 +976,18 @@ DefaultDecorator::_DrawTitle(BRect r) BPoint titlePos; if (fLook != kLeftTitledWindowLook) { - titlePos.x = _closerect.IsValid() ? _closerect.right + fTextOffset - : _tabrect.left + fTextOffset; - titlePos.y = floorf(((_tabrect.top + 2.0) + _tabrect.bottom + fontHeight.ascent + titlePos.x = fCloseRect.IsValid() ? fCloseRect.right + fTextOffset + : fTabRect.left + fTextOffset; + titlePos.y = floorf(((fTabRect.top + 2.0) + fTabRect.bottom + fontHeight.ascent + fontHeight.descent) / 2.0 - fontHeight.descent + 0.5); } else { - titlePos.x = floorf(((_tabrect.left + 2.0) + _tabrect.right + fontHeight.ascent + titlePos.x = floorf(((fTabRect.left + 2.0) + fTabRect.right + fontHeight.ascent + fontHeight.descent) / 2.0 - fontHeight.descent + 0.5); - titlePos.y = _zoomrect.IsValid() ? _zoomrect.top - fTextOffset - : _tabrect.bottom - fTextOffset; + titlePos.y = fZoomRect.IsValid() ? fZoomRect.top - fTextOffset + : fTabRect.bottom - fTextOffset; } - _driver->DrawString(fTruncatedTitle.String(), fTruncatedTitleLength, titlePos, &fDrawState); + fDrawingEngine->DrawString(fTruncatedTitle.String(), fTruncatedTitleLength, titlePos, &fDrawState); } // _DrawZoom @@ -1088,17 +1088,17 @@ DefaultDecorator::_DrawBlendedRect(BRect r, bool down) uint8(startColor.green - (i * gstep)), uint8(startColor.blue - (i * bstep))); - _driver->StrokeLine(BPoint(r.left, r.top + i), + fDrawingEngine->StrokeLine(BPoint(r.left, r.top + i), BPoint(r.left + i, r.top), temprgbcol); temprgbcol.SetColor(uint8(halfColor.red - (i * rstep)), uint8(halfColor.green - (i * gstep)), uint8(halfColor.blue - (i * bstep))); - _driver->StrokeLine(BPoint(r.left + steps, r.top + i), + fDrawingEngine->StrokeLine(BPoint(r.left + steps, r.top + i), BPoint(r.left + i, r.top + steps), temprgbcol); } - _driver->StrokeRect(r, fFrameColors[3]); + fDrawingEngine->StrokeRect(r, fFrameColors[3]); } // _GetButtonSizeAndOffset @@ -1126,29 +1126,29 @@ DefaultDecorator::_LayoutTabItems(const BRect& tabRect) // calulate close rect based on the tab rectangle if (fLook != kLeftTitledWindowLook) { - _closerect.Set(tabRect.left + offset, tabRect.top + offset, + fCloseRect.Set(tabRect.left + offset, tabRect.top + offset, tabRect.left + offset + size, tabRect.top + offset + size); - _zoomrect.Set(tabRect.right - offset - size, tabRect.top + offset, + fZoomRect.Set(tabRect.right - offset - size, tabRect.top + offset, tabRect.right - offset, tabRect.top + offset + size); // hidden buttons have no width if ((Flags() & B_NOT_CLOSABLE) != 0) - _closerect.right = _closerect.left - offset; + fCloseRect.right = fCloseRect.left - offset; if ((Flags() & B_NOT_ZOOMABLE) != 0) - _zoomrect.left = _zoomrect.right + offset; + fZoomRect.left = fZoomRect.right + offset; } else { - _closerect.Set(tabRect.left + offset, tabRect.top + offset, + fCloseRect.Set(tabRect.left + offset, tabRect.top + offset, tabRect.left + offset + size, tabRect.top + offset + size); - _zoomrect.Set(tabRect.left + offset, tabRect.bottom - offset - size, + fZoomRect.Set(tabRect.left + offset, tabRect.bottom - offset - size, tabRect.left + size + offset, tabRect.bottom - offset); // hidden buttons have no height if ((Flags() & B_NOT_CLOSABLE) != 0) - _closerect.bottom = _closerect.top - offset; + fCloseRect.bottom = fCloseRect.top - offset; if ((Flags() & B_NOT_ZOOMABLE) != 0) - _zoomrect.top = _zoomrect.bottom + offset; + fZoomRect.top = fZoomRect.bottom + offset; } // calculate room for title @@ -1156,9 +1156,9 @@ DefaultDecorator::_LayoutTabItems(const BRect& tabRect) // truncated for no apparent reason - OTOH the title does // also not appear perfectly in the middle if (fLook != kLeftTitledWindowLook) - size = (_zoomrect.left - _closerect.right) - fTextOffset * 2 + 2; + size = (fZoomRect.left - fCloseRect.right) - fTextOffset * 2 + 2; else - size = (_zoomrect.top - _closerect.bottom) - fTextOffset * 2 + 2; + size = (fZoomRect.top - fCloseRect.bottom) - fTextOffset * 2 + 2; fTruncatedTitle = Title(); fDrawState.Font().TruncateString(&fTruncatedTitle, B_TRUNCATE_END, size); diff --git a/src/servers/app/Desktop.cpp b/src/servers/app/Desktop.cpp index 2d4dadef42..7a7c874bc2 100644 --- a/src/servers/app/Desktop.cpp +++ b/src/servers/app/Desktop.cpp @@ -2315,11 +2315,11 @@ Desktop::_SetBackground(BRegion& background) dirtyBackground.IntersectWith(&background); fBackgroundRegion = background; if (dirtyBackground.Frame().IsValid()) { - if (GetDrawingEngine()->Lock()) { + if (GetDrawingEngine()->LockParallelAccess()) { GetDrawingEngine()->FillRegion(dirtyBackground, fWorkspaces[fCurrentWorkspace].Color()); - GetDrawingEngine()->Unlock(); + GetDrawingEngine()->UnlockParallelAccess(); } } } diff --git a/src/servers/app/Jamfile b/src/servers/app/Jamfile index 86a3830b5e..c1c5fd6919 100644 --- a/src/servers/app/Jamfile +++ b/src/servers/app/Jamfile @@ -10,6 +10,7 @@ UseFreeTypeHeaders ; Server app_server : Angle.cpp AppServer.cpp + BitfieldRegion.cpp BitmapManager.cpp ClientMemoryAllocator.cpp CursorData.cpp diff --git a/src/servers/app/MultiLocker.h b/src/servers/app/MultiLocker.h index 9a55090fbc..58530d7742 100644 --- a/src/servers/app/MultiLocker.h +++ b/src/servers/app/MultiLocker.h @@ -115,19 +115,27 @@ class AutoReadLocker { AutoReadLocker(MultiLocker* lock) : fLock(*lock) { - fLock.ReadLock(); + fLocked = fLock.ReadLock(); } AutoReadLocker(MultiLocker& lock) : fLock(lock) { - fLock.ReadLock(); + fLocked = fLock.ReadLock(); } ~AutoReadLocker() { - fLock.ReadUnlock(); + Unlock(); + } + void Unlock() + { + if (fLocked) { + fLock.ReadUnlock(); + fLocked = false; + } } private: MultiLocker& fLock; + bool fLocked; }; diff --git a/src/servers/app/OffscreenWindowLayer.cpp b/src/servers/app/OffscreenWindowLayer.cpp index 1a1bf146ff..b51bb50da3 100644 --- a/src/servers/app/OffscreenWindowLayer.cpp +++ b/src/servers/app/OffscreenWindowLayer.cpp @@ -39,11 +39,11 @@ OffscreenWindowLayer::OffscreenWindowLayer(ServerBitmap* bitmap, OffscreenWindowLayer::~OffscreenWindowLayer() { - fHWInterface->WriteLock(); + fHWInterface->LockExclusiveAccess(); // Unlike normal Layers, we own the DrawingEngine instance delete GetDrawingEngine(); fHWInterface->Shutdown(); - fHWInterface->WriteUnlock(); + fHWInterface->UnlockExclusiveAccess(); delete fHWInterface; } diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index 71a1decc3e..b9bd8f8f85 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -1966,10 +1966,8 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li return; } - // prevent other ServerWindows from messing with the drawing engine - // as long as each uses the same instance... TODO: remove the locking - // when each has its own - drawingEngine->Lock(); + drawingEngine->LockParallelAccess(); + // TODO: avoid setting the region each time drawingEngine->ConstrainClippingRegion(&fCurrentDrawingRegion); switch (code) { @@ -2288,7 +2286,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li break; } - drawingEngine->Unlock(); + drawingEngine->UnlockParallelAccess(); } @@ -2698,7 +2696,8 @@ ServerWindow::MakeWindowLayer(BRect frame, const char* name, { // The non-offscreen ServerWindow uses the DrawingEngine instance from the desktop. return new (nothrow) WindowLayer(frame, name, look, feel, flags, - workspace, this, fDesktop->GetDrawingEngine()); +// workspace, this, fDesktop->GetDrawingEngine()); + workspace, this, new DrawingEngine(fDesktop->HWInterface())); } @@ -2830,7 +2829,7 @@ ServerWindow::_SetCurrentLayer(ViewLayer* layer) #if DELAYED_BACKGROUND_CLEARING if (fCurrentLayer && fCurrentLayer->IsBackgroundDirty() && fWindowLayer->InUpdate()) { DrawingEngine* drawingEngine = fWindowLayer->GetDrawingEngine(); - if (drawingEngine->Lock()) { + if (drawingEngine->LockParallelAccess()) { fWindowLayer->GetEffectiveDrawingRegion(fCurrentLayer, fCurrentDrawingRegion); fCurrentDrawingRegionValid = true; @@ -2841,7 +2840,7 @@ ServerWindow::_SetCurrentLayer(ViewLayer* layer) fCurrentLayer->Draw(drawingEngine, &dirty, &content, false); - drawingEngine->Unlock(); + drawingEngine->UnlockParallelAccess(); } } #endif diff --git a/src/servers/app/ViewLayer.cpp b/src/servers/app/ViewLayer.cpp index d82bd6209b..82910c2742 100644 --- a/src/servers/app/ViewLayer.cpp +++ b/src/servers/app/ViewLayer.cpp @@ -1354,8 +1354,13 @@ ViewLayer::AddTokensForLayersInRegion(BPrivate::PortLink& link, if (!fVisible) return; - if (region.Intersects(ScreenClipping(windowContentClipping).Frame())) - link.Attach(fToken); +// if (region.Intersects(ScreenClipping(windowContentClipping).Frame())) + IntRect screenBounds(Bounds()); + ConvertToScreen(&screenBounds); + if (!region.Intersects((clipping_rect)screenBounds)) + return; + + link.Attach(fToken); for (ViewLayer* child = FirstChild(); child; child = child->NextSibling()) child->AddTokensForLayersInRegion(link, region, diff --git a/src/servers/app/WindowLayer.cpp b/src/servers/app/WindowLayer.cpp index 7b65c54020..d7da0ac2fe 100644 --- a/src/servers/app/WindowLayer.cpp +++ b/src/servers/app/WindowLayer.cpp @@ -796,8 +796,9 @@ WindowLayer::MouseDown(BMessage* message, BPoint where, int32* _viewToken) GetBorderRegion(visibleBorder); visibleBorder->IntersectWith(&VisibleRegion()); - fDrawingEngine->Lock(); - fDrawingEngine->ConstrainClippingRegion(visibleBorder); + DrawingEngine* engine = fDecorator->GetDrawingEngine(); + engine->LockExclusiveAccess(); + engine->ConstrainClippingRegion(visibleBorder); if (fIsZooming) { fDecorator->SetZoom(true); @@ -807,7 +808,7 @@ WindowLayer::MouseDown(BMessage* message, BPoint where, int32* _viewToken) fDecorator->SetMinimize(true); } - fDrawingEngine->Unlock(); + engine->UnlockExclusiveAccess(); fRegionPool.Recycle(visibleBorder); @@ -872,8 +873,9 @@ WindowLayer::MouseUp(BMessage* message, BPoint where, int32* _viewToken) GetBorderRegion(visibleBorder); visibleBorder->IntersectWith(&VisibleRegion()); - fDrawingEngine->Lock(); - fDrawingEngine->ConstrainClippingRegion(visibleBorder); + DrawingEngine* engine = fDecorator->GetDrawingEngine(); + engine->LockExclusiveAccess(); + engine->ConstrainClippingRegion(visibleBorder); if (fIsZooming) { fIsZooming = false; @@ -900,7 +902,7 @@ WindowLayer::MouseUp(BMessage* message, BPoint where, int32* _viewToken) } } - fDrawingEngine->Unlock(); + engine->UnlockExclusiveAccess(); fRegionPool.Recycle(visibleBorder); } @@ -959,8 +961,9 @@ WindowLayer::MouseMoved(BMessage *message, BPoint where, int32* _viewToken, GetBorderRegion(visibleBorder); visibleBorder->IntersectWith(&VisibleRegion()); - fDrawingEngine->Lock(); - fDrawingEngine->ConstrainClippingRegion(visibleBorder); + DrawingEngine* engine = fDecorator->GetDrawingEngine(); + engine->LockExclusiveAccess(); + engine->ConstrainClippingRegion(visibleBorder); if (fIsZooming) { fDecorator->SetZoom(_ActionFor(message) == DEC_ZOOM); @@ -970,7 +973,7 @@ WindowLayer::MouseMoved(BMessage *message, BPoint where, int32* _viewToken, fDecorator->SetMinimize(_ActionFor(message) == DEC_MINIMIZE); } - fDrawingEngine->Unlock(); + engine->UnlockExclusiveAccess(); fRegionPool.Recycle(visibleBorder); } @@ -1737,14 +1740,14 @@ WindowLayer::_TriggerContentRedraw(BRegion& dirtyContentRegion) backgroundClearingRegion = &fPendingUpdateSession.DirtyRegion(); } - if (fDrawingEngine->Lock()) { + if (fDrawingEngine->LockParallelAccess()) { fDrawingEngine->SuspendAutoSync(); fTopLayer->Draw(fDrawingEngine, backgroundClearingRegion, &fContentRegion, true); fDrawingEngine->Sync(); - fDrawingEngine->Unlock(); + fDrawingEngine->UnlockParallelAccess(); } } } @@ -1771,16 +1774,20 @@ WindowLayer::_DrawBorder() // intersect with the dirty region dirtyBorderRegion->IntersectWith(&fDirtyRegion); - if (dirtyBorderRegion->CountRects() > 0 && fDrawingEngine->Lock()) { - fDrawingEngine->ConstrainClippingRegion(dirtyBorderRegion); + DrawingEngine* engine = fDecorator->GetDrawingEngine(); + if (dirtyBorderRegion->CountRects() > 0 && engine->LockExclusiveAccess()) { + engine->ConstrainClippingRegion(dirtyBorderRegion); fDecorator->Draw(dirtyBorderRegion->Frame()); - fDrawingEngine->Unlock(); + engine->UnlockExclusiveAccess(); } fRegionPool.Recycle(dirtyBorderRegion); } +//static rgb_color sPendingColor; +//static rgb_color sCurrentColor; + /*! pre: the clipping is readlocked (this function is only called from _TriggerContentRedraw()), which @@ -1793,7 +1800,7 @@ WindowLayer::_TransferToUpdateSession(BRegion* contentDirtyRegion) if (contentDirtyRegion->CountRects() <= 0) return; -//fDrawingEngine->FillRegion(*contentDirtyRegion, RGBColor(255, 255, 0, 255)); +//fDrawingEngine->FillRegion(*contentDirtyRegion, RGBColor(sPendingColor)); //snooze(10000); // add to pending @@ -1873,6 +1880,15 @@ WindowLayer::BeginUpdate(BPrivate::PortLink& link) dirty->IntersectWith(&VisibleContentRegion()); +//sCurrentColor.red = rand() % 255; +//sCurrentColor.green = rand() % 255; +//sCurrentColor.blue = rand() % 255; +//sPendingColor.red = rand() % 255; +//sPendingColor.green = rand() % 255; +//sPendingColor.blue = rand() % 255; +//fDrawingEngine->FillRegion(*dirty, RGBColor(sCurrentColor)); +//snooze(10000); + link.StartMessage(B_OK); // append the current window geometry to the // message, the client will need it @@ -1888,7 +1904,7 @@ WindowLayer::BeginUpdate(BPrivate::PortLink& link) link.Attach(B_NULL_TOKEN); link.Flush(); - if (!fCurrentUpdateSession.IsExpose() && fDrawingEngine->Lock()) { + if (!fCurrentUpdateSession.IsExpose() && fDrawingEngine->LockParallelAccess()) { //fDrawingEngine->FillRegion(dirty, RGBColor(255, 0, 0, 255)); fDrawingEngine->SuspendAutoSync(); @@ -1896,7 +1912,7 @@ WindowLayer::BeginUpdate(BPrivate::PortLink& link) &fContentRegion, true); fDrawingEngine->Sync(); - fDrawingEngine->Unlock(); + fDrawingEngine->UnlockParallelAccess(); } // else the background was cleared already fRegionPool.Recycle(dirty); diff --git a/src/servers/app/drawing/AccelerantHWInterface.cpp b/src/servers/app/drawing/AccelerantHWInterface.cpp index 68a19aaf93..eec1be2251 100644 --- a/src/servers/app/drawing/AccelerantHWInterface.cpp +++ b/src/servers/app/drawing/AccelerantHWInterface.cpp @@ -545,9 +545,9 @@ AccelerantHWInterface::SetMode(const display_mode& mode) void AccelerantHWInterface::GetMode(display_mode *mode) { - if (mode && ReadLock()) { + if (mode && LockParallelAccess()) { *mode = fDisplayMode; - ReadUnlock(); + UnlockParallelAccess(); } } @@ -997,13 +997,13 @@ void AccelerantHWInterface::SetCursor(ServerCursor* cursor) { HWInterface::SetCursor(cursor); -// if (WriteLock()) { +// if (LockExclusiveAccess()) { // TODO: implement setting the hard ware cursor // NOTE: cursor should be always B_RGBA32 // NOTE: The HWInterface implementation should // still be called, since it takes ownership of // the cursor. -// WriteUnlock(); +// UnlockExclusiveAccess(); // } } @@ -1012,9 +1012,9 @@ void AccelerantHWInterface::SetCursorVisible(bool visible) { HWInterface::SetCursorVisible(visible); -// if (WriteLock()) { +// if (LockExclusiveAccess()) { // TODO: update graphics hardware -// WriteUnlock(); +// UnlockExclusiveAccess(); // } } @@ -1023,9 +1023,9 @@ void AccelerantHWInterface::MoveCursorTo(const float& x, const float& y) { HWInterface::MoveCursorTo(x, y); -// if (WriteLock()) { +// if (LockExclusiveAccess()) { // TODO: update graphics hardware -// WriteUnlock(); +// UnlockExclusiveAccess(); // } } diff --git a/src/servers/app/drawing/DrawingEngine.cpp b/src/servers/app/drawing/DrawingEngine.cpp index e6e17f124d..3734b1e579 100644 --- a/src/servers/app/drawing/DrawingEngine.cpp +++ b/src/servers/app/drawing/DrawingEngine.cpp @@ -23,7 +23,10 @@ #include "drawing_support.h" #define CRASH_IF_NOT_LOCKED -//#define CRASH_IF_NOT_LOCKED if (!IsLocked()) debugger("not locked!"); +//#define CRASH_IF_NOT_LOCKED if (!IsParallelAccessLocked()) debugger("not parallel locked!"); + +#define CRASH_IF_NOT_EXCLUSIVE_LOCKED +//#define CRASH_IF_NOT_EXCLUSIVE_LOCKED if (!IsExclusiveAccessLocked()) debugger("not exclusive locked!"); // make_rect_valid static inline void @@ -97,6 +100,38 @@ DrawingEngine::~DrawingEngine() } +// #pragma mark - locking + + +bool +DrawingEngine::LockParallelAccess() +{ + return fGraphicsCard->LockExclusiveAccess(); +} + + +void +DrawingEngine::UnlockParallelAccess() +{ + fGraphicsCard->UnlockExclusiveAccess(); +} + + +bool +DrawingEngine::LockExclusiveAccess() +{ + return fGraphicsCard->LockExclusiveAccess(); +} + + +void +DrawingEngine::UnlockExclusiveAccess() +{ + fGraphicsCard->UnlockExclusiveAccess(); +} + +// #pragma mark - + void DrawingEngine::FrameBufferChanged() { @@ -106,11 +141,13 @@ DrawingEngine::FrameBufferChanged() return; } - if (WriteLock()) { + // NOTE: locking is probably bogus, since we are called + // in the thread that changed the frame buffer... + if (LockExclusiveAccess()) { fPainter->AttachToBuffer(fGraphicsCard->DrawingBuffer()); // available HW acceleration might have changed fAvailableHWAccleration = fGraphicsCard->AvailableHWAcceleration(); - WriteUnlock(); + UnlockExclusiveAccess(); } } @@ -212,11 +249,11 @@ DrawingEngine::Sync() // Since A is to the left of C and B is to the top of C, The "node" // for C will point to the nodes of A and B as its "successors". Therefor, // A and B will have an "indegree" of 1 for C pointing to them. C will -// have and "indegree" of 0, because there was no rect to which C +// have an "indegree" of 0, because there was no rect to which C // was to the left or top of. When comparing A and B, neither is left // or top from the other and in the sense that the algorithm cares about. -// NOTE: comparisson of coordinates assumes that rects don't overlap +// NOTE: comparison of coordinates assumes that rects don't overlap // and don't share the actual edge either (as is the case in BRegions). struct node { @@ -263,12 +300,12 @@ struct node { int32 next_pointer; }; -bool +static bool is_left_of(const BRect& a, const BRect& b) { return (a.right < b.left); } -bool +static bool is_above(const BRect& a, const BRect& b) { return (a.bottom < b.top); @@ -279,150 +316,142 @@ void DrawingEngine::CopyRegion(/*const*/ BRegion* region, int32 xOffset, int32 yOffset) { - // NOTE: Write locking because we might use HW acceleration. - // This needs to be investigated, I'm doing this because of - // gut feeling. - if (WriteLock()) { - BRect frame = region->Frame(); - frame = frame | frame.OffsetByCopy(xOffset, yOffset); - fGraphicsCard->HideSoftwareCursor(frame); + CRASH_IF_NOT_EXCLUSIVE_LOCKED - int32 count = region->CountRects(); + BRect frame = region->Frame(); + frame = frame | frame.OffsetByCopy(xOffset, yOffset); + bool cursorTouched = fGraphicsCard->HideSoftwareCursor(frame); - // TODO: make this step unnecessary - // (by using different stack impl inside node) - node nodes[count]; - for (int32 i= 0; i < count; i++) { - nodes[i].init(region->RectAt(i), count); - } + int32 count = region->CountRects(); - for (int32 i = 0; i < count; i++) { - BRect a = region->RectAt(i); - for (int32 k = i + 1; k < count; k++) { - BRect b = region->RectAt(k); - int cmp = 0; - // compare horizontally - if (xOffset > 0) { - if (is_left_of(a, b)) { - cmp -= 1; - } else if (is_left_of(b, a)) { - cmp += 1; - } - } else if (xOffset < 0) { - if (is_left_of(a, b)) { - cmp += 1; - } else if (is_left_of(b, a)) { - cmp -= 1; - } - } - // compare vertically - if (yOffset > 0) { - if (is_above(a, b)) { - cmp -= 1; - } else if (is_above(b, a)) { - cmp += 1; - } - } else if (yOffset < 0) { - if (is_above(a, b)) { - cmp += 1; - } else if (is_above(b, a)) { - cmp -= 1; - } - } - // add appropriate node as successor - if (cmp > 0) { - nodes[i].push(&nodes[k]); - nodes[k].in_degree++; - } else if (cmp < 0) { - nodes[k].push(&nodes[i]); - nodes[i].in_degree++; - } - } - } - // put all nodes onto a stack that have an "indegree" count of zero - stack inDegreeZeroNodes; - for (int32 i = 0; i < count; i++) { - if (nodes[i].in_degree == 0) { - inDegreeZeroNodes.push(&nodes[i]); - } - } - // pop the rects from the stack, do the actual copy operation - // and decrease the "indegree" count of the other rects not - // currently on the stack and to which the current rect pointed - // to. If their "indegree" count reaches zero, put them onto the - // stack as well. - - clipping_rect* sortedRectList = NULL; - int32 nextSortedIndex = 0; - - if (fAvailableHWAccleration & HW_ACC_COPY_REGION) - sortedRectList = new clipping_rect[count]; - - while (!inDegreeZeroNodes.empty()) { - node* n = inDegreeZeroNodes.top(); - inDegreeZeroNodes.pop(); - - // do the software implementation or add to sorted - // rect list for using the HW accelerated version - // later - if (sortedRectList) { - sortedRectList[nextSortedIndex].left = (int32)n->rect.left; - sortedRectList[nextSortedIndex].top = (int32)n->rect.top; - sortedRectList[nextSortedIndex].right = (int32)n->rect.right; - sortedRectList[nextSortedIndex].bottom = (int32)n->rect.bottom; - nextSortedIndex++; - } else { - BRect touched = _CopyRect(n->rect, xOffset, yOffset); - fGraphicsCard->Invalidate(touched); - } - - for (int32 k = 0; k < n->next_pointer; k++) { - n->pointers[k]->in_degree--; - if (n->pointers[k]->in_degree == 0) - inDegreeZeroNodes.push(n->pointers[k]); - } - } - - // trigger the HW accelerated version if is was available - if (sortedRectList) - fGraphicsCard->CopyRegion(sortedRectList, count, xOffset, yOffset); - - delete[] sortedRectList; - - fGraphicsCard->ShowSoftwareCursor(); - - WriteUnlock(); + // TODO: make this step unnecessary + // (by using different stack impl inside node) + node nodes[count]; + for (int32 i= 0; i < count; i++) { + nodes[i].init(region->RectAt(i), count); } + + for (int32 i = 0; i < count; i++) { + BRect a = region->RectAt(i); + for (int32 k = i + 1; k < count; k++) { + BRect b = region->RectAt(k); + int cmp = 0; + // compare horizontally + if (xOffset > 0) { + if (is_left_of(a, b)) { + cmp -= 1; + } else if (is_left_of(b, a)) { + cmp += 1; + } + } else if (xOffset < 0) { + if (is_left_of(a, b)) { + cmp += 1; + } else if (is_left_of(b, a)) { + cmp -= 1; + } + } + // compare vertically + if (yOffset > 0) { + if (is_above(a, b)) { + cmp -= 1; + } else if (is_above(b, a)) { + cmp += 1; + } + } else if (yOffset < 0) { + if (is_above(a, b)) { + cmp += 1; + } else if (is_above(b, a)) { + cmp -= 1; + } + } + // add appropriate node as successor + if (cmp > 0) { + nodes[i].push(&nodes[k]); + nodes[k].in_degree++; + } else if (cmp < 0) { + nodes[k].push(&nodes[i]); + nodes[i].in_degree++; + } + } + } + // put all nodes onto a stack that have an "indegree" count of zero + stack inDegreeZeroNodes; + for (int32 i = 0; i < count; i++) { + if (nodes[i].in_degree == 0) { + inDegreeZeroNodes.push(&nodes[i]); + } + } + // pop the rects from the stack, do the actual copy operation + // and decrease the "indegree" count of the other rects not + // currently on the stack and to which the current rect pointed + // to. If their "indegree" count reaches zero, put them onto the + // stack as well. + + clipping_rect* sortedRectList = NULL; + int32 nextSortedIndex = 0; + + if (fAvailableHWAccleration & HW_ACC_COPY_REGION) + sortedRectList = new clipping_rect[count]; + + while (!inDegreeZeroNodes.empty()) { + node* n = inDegreeZeroNodes.top(); + inDegreeZeroNodes.pop(); + + // do the software implementation or add to sorted + // rect list for using the HW accelerated version + // later + if (sortedRectList) { + sortedRectList[nextSortedIndex].left = (int32)n->rect.left; + sortedRectList[nextSortedIndex].top = (int32)n->rect.top; + sortedRectList[nextSortedIndex].right = (int32)n->rect.right; + sortedRectList[nextSortedIndex].bottom = (int32)n->rect.bottom; + nextSortedIndex++; + } else { + BRect touched = _CopyRect(n->rect, xOffset, yOffset); + fGraphicsCard->Invalidate(touched); + } + + for (int32 k = 0; k < n->next_pointer; k++) { + n->pointers[k]->in_degree--; + if (n->pointers[k]->in_degree == 0) + inDegreeZeroNodes.push(n->pointers[k]); + } + } + + // trigger the HW accelerated version if is was available + if (sortedRectList) + fGraphicsCard->CopyRegion(sortedRectList, count, xOffset, yOffset); + + delete[] sortedRectList; + + if (cursorTouched) + fGraphicsCard->ShowSoftwareCursor(); } // InvertRect void DrawingEngine::InvertRect(BRect r) { - // NOTE: Write locking because we might use HW acceleration. - // This needs to be investigated, I'm doing this because of - // gut feeling. - if (WriteLock()) { - make_rect_valid(r); - r = fPainter->ClipRect(r); - if (r.IsValid()) { - fGraphicsCard->HideSoftwareCursor(r); + CRASH_IF_NOT_LOCKED - // try hardware optimized version first - if (fAvailableHWAccleration & HW_ACC_INVERT_REGION) { - BRegion region(r); - region.IntersectWith(fPainter->ClippingRegion()); - fGraphicsCard->InvertRegion(region); - } else { - fPainter->InvertRect(r); + make_rect_valid(r); + r = fPainter->ClipRect(r); + if (r.IsValid()) { + bool cursorTouched = fGraphicsCard->HideSoftwareCursor(r); - fGraphicsCard->Invalidate(r); - } + // try hardware optimized version first + if (fAvailableHWAccleration & HW_ACC_INVERT_REGION) { + BRegion region(r); + region.IntersectWith(fPainter->ClippingRegion()); + fGraphicsCard->InvertRegion(region); + } else { + fPainter->InvertRect(r); - fGraphicsCard->ShowSoftwareCursor(); + fGraphicsCard->Invalidate(r); } - WriteUnlock(); + if (cursorTouched) + fGraphicsCard->ShowSoftwareCursor(); } } @@ -436,13 +465,14 @@ DrawingEngine::DrawBitmap(ServerBitmap *bitmap, BRect clipped = fPainter->ClipRect(dest); if (clipped.IsValid()) { - fGraphicsCard->HideSoftwareCursor(clipped); + bool cursorTouched = fGraphicsCard->HideSoftwareCursor(clipped); fPainter->SetDrawState(d); fPainter->DrawBitmap(bitmap, source, dest); fGraphicsCard->Invalidate(clipped); - fGraphicsCard->ShowSoftwareCursor(); + if (cursorTouched) + fGraphicsCard->ShowSoftwareCursor(); } } @@ -460,7 +490,7 @@ DrawingEngine::DrawArc(BRect r, const float &angle, extend_by_stroke_width(clipped, d); clipped = fPainter->ClipRect(r); if (clipped.IsValid()) { - fGraphicsCard->HideSoftwareCursor(clipped); + bool cursorTouched = fGraphicsCard->HideSoftwareCursor(clipped); fPainter->SetDrawState(d); @@ -475,7 +505,8 @@ DrawingEngine::DrawArc(BRect r, const float &angle, fPainter->StrokeArc(center, xRadius, yRadius, angle, span); fGraphicsCard->Invalidate(clipped); - fGraphicsCard->ShowSoftwareCursor(); + if (cursorTouched) + fGraphicsCard->ShowSoftwareCursor(); } } @@ -516,13 +547,14 @@ DrawingEngine::DrawEllipse(BRect r, const DrawState *d, bool filled) clipped = fPainter->ClipRect(clipped); if (clipped.IsValid()) { - fGraphicsCard->HideSoftwareCursor(clipped); + bool cursorTouched = fGraphicsCard->HideSoftwareCursor(clipped); fPainter->SetDrawState(d); fPainter->DrawEllipse(r, filled); fGraphicsCard->Invalidate(clipped); - fGraphicsCard->ShowSoftwareCursor(); + if (cursorTouched) + fGraphicsCard->ShowSoftwareCursor(); } } @@ -539,13 +571,14 @@ DrawingEngine::DrawPolygon(BPoint* ptlist, int32 numpts, extend_by_stroke_width(bounds, d); bounds = fPainter->ClipRect(bounds); if (bounds.IsValid()) { - fGraphicsCard->HideSoftwareCursor(bounds); + bool cursorTouched = fGraphicsCard->HideSoftwareCursor(bounds); fPainter->SetDrawState(d); fPainter->DrawPolygon(ptlist, numpts, filled, closed); fGraphicsCard->Invalidate(bounds); - fGraphicsCard->ShowSoftwareCursor(); + if (cursorTouched) + fGraphicsCard->ShowSoftwareCursor(); } } @@ -562,27 +595,26 @@ DrawingEngine::StrokePoint(const BPoint& pt, const RGBColor &color) // * this function is only used by Decorators // * it assumes a one pixel wide line void -DrawingEngine::StrokeLine(const BPoint &start, const BPoint &end, const RGBColor &color) +DrawingEngine::StrokeLine(const BPoint &start, const BPoint &end, + const RGBColor &color) { CRASH_IF_NOT_LOCKED - if (Lock()) { - BRect touched(start, end); - make_rect_valid(touched); - touched = fPainter->ClipRect(touched); - fGraphicsCard->HideSoftwareCursor(touched); + BRect touched(start, end); + make_rect_valid(touched); + touched = fPainter->ClipRect(touched); + bool cursorTouched = fGraphicsCard->HideSoftwareCursor(touched); - if (!fPainter->StraightLine(start, end, color.GetColor32())) { - DrawState context; - context.SetHighColor(color); - context.SetDrawingMode(B_OP_OVER); - StrokeLine(start, end, &context); - } else { - fGraphicsCard->Invalidate(touched); - } - fGraphicsCard->ShowSoftwareCursor(); - Unlock(); + if (!fPainter->StraightLine(start, end, color.GetColor32())) { + DrawState context; + context.SetHighColor(color); + context.SetDrawingMode(B_OP_OVER); + StrokeLine(start, end, &context); + } else { + fGraphicsCard->Invalidate(touched); } + if (cursorTouched) + fGraphicsCard->ShowSoftwareCursor(); } // this function is used to draw a one pixel wide rect @@ -591,19 +623,16 @@ DrawingEngine::StrokeRect(BRect r, const RGBColor &color) { CRASH_IF_NOT_LOCKED - if (Lock()) { - make_rect_valid(r); - BRect clipped = fPainter->ClipRect(r); - if (clipped.IsValid()) { - fGraphicsCard->HideSoftwareCursor(clipped); - - fPainter->StrokeRect(r, color.GetColor32()); - - fGraphicsCard->Invalidate(clipped); - fGraphicsCard->ShowSoftwareCursor(); - } + make_rect_valid(r); + BRect clipped = fPainter->ClipRect(r); + if (clipped.IsValid()) { + bool cursorTouched = fGraphicsCard->HideSoftwareCursor(clipped); - Unlock(); + fPainter->StrokeRect(r, color.GetColor32()); + + fGraphicsCard->Invalidate(clipped); + if (cursorTouched) + fGraphicsCard->ShowSoftwareCursor(); } } @@ -616,30 +645,26 @@ DrawingEngine::FillRect(BRect 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. - if (WriteLock()) { - make_rect_valid(r); - r = fPainter->ClipRect(r); - if (r.IsValid()) { - bool cursorTouched = fGraphicsCard->HideSoftwareCursor(r); - - // try hardware optimized version first - if (fAvailableHWAccleration & HW_ACC_FILL_REGION) { - BRegion region(r); - region.IntersectWith(fPainter->ClippingRegion()); - fGraphicsCard->FillRegion(region, color, - fSuspendSyncLevel == 0 - || cursorTouched); - } else { - fPainter->FillRect(r, color.GetColor32()); - - fGraphicsCard->Invalidate(r); - } + make_rect_valid(r); + r = fPainter->ClipRect(r); + if (r.IsValid()) { + bool cursorTouched = fGraphicsCard->HideSoftwareCursor(r); - if (cursorTouched) - fGraphicsCard->ShowSoftwareCursor(); + // try hardware optimized version first + if (fAvailableHWAccleration & HW_ACC_FILL_REGION) { + BRegion region(r); + region.IntersectWith(fPainter->ClippingRegion()); + fGraphicsCard->FillRegion(region, color, + fSuspendSyncLevel == 0 + || cursorTouched); + } else { + fPainter->FillRect(r, color.GetColor32()); + + fGraphicsCard->Invalidate(r); } - WriteUnlock(); + if (cursorTouched) + fGraphicsCard->ShowSoftwareCursor(); } } @@ -649,38 +674,31 @@ DrawingEngine::FillRegion(BRegion& r, const RGBColor& color) { CRASH_IF_NOT_LOCKED - // 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 frame = r.Frame(); - bool cursorTouched = fGraphicsCard->HideSoftwareCursor(frame); + BRect frame = r.Frame(); + bool cursorTouched = fGraphicsCard->HideSoftwareCursor(frame); - bool doInSoftware = true; - // try hardware optimized version first - if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) != 0 - && frame.Width() * frame.Height() > 100) { - fGraphicsCard->FillRegion(r, color, fSuspendSyncLevel == 0 - || cursorTouched); - doInSoftware = false; - } - - if (doInSoftware) { - - int32 count = r.CountRects(); - for (int32 i = 0; i < count; i++) { - fPainter->FillRectNoClipping(r.RectAt(i), color.GetColor32()); - } - - fGraphicsCard->Invalidate(frame); - } - - if (cursorTouched) - fGraphicsCard->ShowSoftwareCursor(); - - WriteUnlock(); + bool doInSoftware = true; + // try hardware optimized version first + if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) != 0 + && frame.Width() * frame.Height() > 100) { + fGraphicsCard->FillRegion(r, color, fSuspendSyncLevel == 0 + || cursorTouched); + doInSoftware = false; } + + if (doInSoftware) { + + int32 count = r.CountRects(); + for (int32 i = 0; i < count; i++) { + fPainter->FillRectNoClipping(r.RectAt(i), color.GetColor32()); + } + + fGraphicsCard->Invalidate(frame); + } + + if (cursorTouched) + fGraphicsCard->ShowSoftwareCursor(); } // #pragma mark - DrawState @@ -697,13 +715,14 @@ DrawingEngine::StrokeRect(BRect r, const DrawState *d) clipped = fPainter->ClipRect(clipped); if (clipped.IsValid()) { - fGraphicsCard->HideSoftwareCursor(clipped); + bool cursorTouched = fGraphicsCard->HideSoftwareCursor(clipped); fPainter->SetDrawState(d); fPainter->StrokeRect(r); fGraphicsCard->Invalidate(clipped); - fGraphicsCard->ShowSoftwareCursor(); + if (cursorTouched) + fGraphicsCard->ShowSoftwareCursor(); } } @@ -713,52 +732,45 @@ DrawingEngine::FillRect(BRect r, const DrawState *d) { CRASH_IF_NOT_LOCKED - // NOTE: Write locking because we might use HW acceleration. - // This needs to be investigated, I'm doing this because of - // gut feeling. - if (WriteLock()) { - make_rect_valid(r); - r = fPainter->ClipRect(r); - if (r.IsValid()) { - bool cursorTouched = fGraphicsCard->HideSoftwareCursor(r); + make_rect_valid(r); + r = fPainter->ClipRect(r); + if (r.IsValid()) { + bool cursorTouched = fGraphicsCard->HideSoftwareCursor(r); - bool doInSoftware = true; - if ((r.Width() + 1) * (r.Height() + 1) > 100.0) { - // try hardware optimized version first - // if the rect is large enough - if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) != 0) { - if (d->GetPattern() == B_SOLID_HIGH - && (d->GetDrawingMode() == B_OP_COPY - || d->GetDrawingMode() == B_OP_OVER)) { - BRegion region(r); - region.IntersectWith(fPainter->ClippingRegion()); - fGraphicsCard->FillRegion(region, d->HighColor(), - fSuspendSyncLevel == 0 - || cursorTouched); - doInSoftware = false; - } else if (d->GetPattern() == B_SOLID_LOW - && d->GetDrawingMode() == B_OP_COPY) { - BRegion region(r); - region.IntersectWith(fPainter->ClippingRegion()); - fGraphicsCard->FillRegion(region, d->LowColor(), - fSuspendSyncLevel == 0 - || cursorTouched); - doInSoftware = false; - } + bool doInSoftware = true; + if ((r.Width() + 1) * (r.Height() + 1) > 100.0) { + // try hardware optimized version first + // if the rect is large enough + if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) != 0) { + if (d->GetPattern() == B_SOLID_HIGH + && (d->GetDrawingMode() == B_OP_COPY + || d->GetDrawingMode() == B_OP_OVER)) { + BRegion region(r); + region.IntersectWith(fPainter->ClippingRegion()); + fGraphicsCard->FillRegion(region, d->HighColor(), + fSuspendSyncLevel == 0 + || cursorTouched); + doInSoftware = false; + } else if (d->GetPattern() == B_SOLID_LOW + && d->GetDrawingMode() == B_OP_COPY) { + BRegion region(r); + region.IntersectWith(fPainter->ClippingRegion()); + fGraphicsCard->FillRegion(region, d->LowColor(), + fSuspendSyncLevel == 0 + || cursorTouched); + doInSoftware = false; } } - if (doInSoftware) { - fPainter->SetDrawState(d); - fPainter->FillRect(r); + } + if (doInSoftware) { + fPainter->SetDrawState(d); + fPainter->FillRect(r); - fGraphicsCard->Invalidate(r); - } - - if (cursorTouched) - fGraphicsCard->ShowSoftwareCursor(); + fGraphicsCard->Invalidate(r); } - WriteUnlock(); + if (cursorTouched) + fGraphicsCard->ShowSoftwareCursor(); } } @@ -768,53 +780,46 @@ DrawingEngine::FillRegion(BRegion& r, const DrawState *d) { CRASH_IF_NOT_LOCKED - // NOTE: Write locking because we might use HW acceleration. - // This needs to be investigated, I'm doing this because of - // gut feeling. - if (WriteLock()) { - BRect clipped = fPainter->ClipRect(r.Frame()); - if (clipped.IsValid()) { - bool cursorTouched = fGraphicsCard->HideSoftwareCursor(clipped); + BRect clipped = fPainter->ClipRect(r.Frame()); + if (clipped.IsValid()) { + bool cursorTouched = fGraphicsCard->HideSoftwareCursor(clipped); - bool doInSoftware = true; - // try hardware optimized version first - if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) != 0) { - if (d->GetPattern() == B_SOLID_HIGH - && (d->GetDrawingMode() == B_OP_COPY - || d->GetDrawingMode() == B_OP_OVER)) { - r.IntersectWith(fPainter->ClippingRegion()); - fGraphicsCard->FillRegion(r, d->HighColor(), - fSuspendSyncLevel == 0 - || cursorTouched); - doInSoftware = false; - } else if (d->GetPattern() == B_SOLID_LOW - && d->GetDrawingMode() == B_OP_COPY) { - r.IntersectWith(fPainter->ClippingRegion()); - fGraphicsCard->FillRegion(r, d->LowColor(), - fSuspendSyncLevel == 0 - || cursorTouched); - doInSoftware = false; - } + bool doInSoftware = true; + // try hardware optimized version first + if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) != 0) { + if (d->GetPattern() == B_SOLID_HIGH + && (d->GetDrawingMode() == B_OP_COPY + || d->GetDrawingMode() == B_OP_OVER)) { + r.IntersectWith(fPainter->ClippingRegion()); + fGraphicsCard->FillRegion(r, d->HighColor(), + fSuspendSyncLevel == 0 + || cursorTouched); + doInSoftware = false; + } else if (d->GetPattern() == B_SOLID_LOW + && d->GetDrawingMode() == B_OP_COPY) { + r.IntersectWith(fPainter->ClippingRegion()); + fGraphicsCard->FillRegion(r, d->LowColor(), + fSuspendSyncLevel == 0 + || cursorTouched); + doInSoftware = false; } - - if (doInSoftware) { - fPainter->SetDrawState(d); - - BRect touched = fPainter->FillRect(r.RectAt(0)); - - int32 count = r.CountRects(); - for (int32 i = 1; i < count; i++) { - touched = touched | fPainter->FillRect(r.RectAt(i)); - } - - fGraphicsCard->Invalidate(touched); - } - - if (cursorTouched) - fGraphicsCard->ShowSoftwareCursor(); } - WriteUnlock(); + if (doInSoftware) { + fPainter->SetDrawState(d); + + BRect touched = fPainter->FillRect(r.RectAt(0)); + + int32 count = r.CountRects(); + for (int32 i = 1; i < count; i++) { + touched = touched | fPainter->FillRect(r.RectAt(i)); + } + + fGraphicsCard->Invalidate(touched); + } + + if (cursorTouched) + fGraphicsCard->ShowSoftwareCursor(); } } @@ -836,14 +841,15 @@ DrawingEngine::DrawRoundRect(BRect r, float xrad, float yrad, clipped.bottom = ceilf(clipped.bottom); if (clipped.IsValid()) { - fGraphicsCard->HideSoftwareCursor(clipped); + bool cursorTouched = fGraphicsCard->HideSoftwareCursor(clipped); fPainter->SetDrawState(d); BRect touched = filled ? fPainter->FillRoundRect(r, xrad, yrad) : fPainter->StrokeRoundRect(r, xrad, yrad); fGraphicsCard->Invalidate(touched); - fGraphicsCard->ShowSoftwareCursor(); + if (cursorTouched) + fGraphicsCard->ShowSoftwareCursor(); } } @@ -880,7 +886,7 @@ DrawingEngine::DrawTriangle(BPoint* pts, const BRect& bounds, extend_by_stroke_width(clipped, d); clipped = fPainter->ClipRect(clipped); if (clipped.IsValid()) { - fGraphicsCard->HideSoftwareCursor(clipped); + bool cursorTouched = fGraphicsCard->HideSoftwareCursor(clipped); fPainter->SetDrawState(d); if (filled) @@ -889,7 +895,8 @@ DrawingEngine::DrawTriangle(BPoint* pts, const BRect& bounds, fPainter->StrokeTriangle(pts[0], pts[1], pts[2]); fGraphicsCard->Invalidate(clipped); - fGraphicsCard->ShowSoftwareCursor(); + if (cursorTouched) + fGraphicsCard->ShowSoftwareCursor(); } } @@ -904,13 +911,14 @@ DrawingEngine::StrokeLine(const BPoint &start, const BPoint &end, DrawState* con extend_by_stroke_width(touched, context); touched = fPainter->ClipRect(touched); if (touched.IsValid()) { - fGraphicsCard->HideSoftwareCursor(touched); + bool cursorTouched = fGraphicsCard->HideSoftwareCursor(touched); fPainter->SetDrawState(context); fPainter->StrokeLine(start, end); fGraphicsCard->Invalidate(touched); - fGraphicsCard->ShowSoftwareCursor(); + if (cursorTouched) + fGraphicsCard->ShowSoftwareCursor(); } } @@ -942,7 +950,7 @@ DrawingEngine::StrokeLineArray(int32 numLines, extend_by_stroke_width(touched, d); touched = fPainter->ClipRect(touched); if (touched.IsValid()) { - fGraphicsCard->HideSoftwareCursor(touched); + bool cursorTouched = fGraphicsCard->HideSoftwareCursor(touched); data = (const LineArrayData *)&(linedata[0]); @@ -964,7 +972,8 @@ DrawingEngine::StrokeLineArray(int32 numLines, } fGraphicsCard->Invalidate(touched); - fGraphicsCard->ShowSoftwareCursor(); + if (cursorTouched) + fGraphicsCard->ShowSoftwareCursor(); } } @@ -996,14 +1005,15 @@ DrawingEngine::DrawString(const char* string, int32 length, b = fPainter->ClipRect(b); if (b.IsValid()) { //printf("bounding box '%s': %lld µs\n", string, system_time() - now); - fGraphicsCard->HideSoftwareCursor(b); + bool cursorTouched = fGraphicsCard->HideSoftwareCursor(b); //now = system_time(); BRect touched = fPainter->DrawString(string, length, pt, delta); //printf("drawing string: %lld µs\n", system_time() - now); fGraphicsCard->Invalidate(touched); - fGraphicsCard->ShowSoftwareCursor(); + if (cursorTouched) + fGraphicsCard->ShowSoftwareCursor(); } return penLocation; @@ -1018,16 +1028,13 @@ DrawingEngine::StringWidth(const char* string, int32 length, FontLocker locker(d); float width = 0.0; -// if (Lock()) { // NOTE: For now it is enough to block on the // font style lock, this already prevents multiple // threads from executing this code and avoids a // deadlock in case another thread holds the font // lock already and then tries to lock the drawing // engine after it is already locked here (race condition) - width = fPainter->StringWidth(string, length, d); -// Unlock(); -// } + width = fPainter->StringWidth(string, length, d); return width; } @@ -1049,77 +1056,37 @@ DrawingEngine::StringHeight(const char *string, int32 length, FontLocker locker(d); float height = 0.0; -// if (Lock()) { // NOTE: For now it is enough to block on the // font style lock, this already prevents multiple // threads from executing this code and avoids a // deadlock in case another thread holds the font // lock already and then tries to lock the drawing // engine after it is already locked here (race condition) - fPainter->SetDrawState(d, true); - BPoint dummy1(0.0, 0.0); - BPoint dummy2(0.0, 0.0); - height = fPainter->BoundingBox(string, length, dummy1, &dummy2).Height(); -// Unlock(); -// } + fPainter->SetDrawState(d, true); + BPoint dummy1(0.0, 0.0); + BPoint dummy2(0.0, 0.0); + height = fPainter->BoundingBox(string, length, dummy1, &dummy2).Height(); return height; } // #pragma mark - -// Lock -bool -DrawingEngine::Lock() -{ - return fGraphicsCard->WriteLock(); -} - -// Unlock -void -DrawingEngine::Unlock() -{ - fGraphicsCard->WriteUnlock(); -} - -// IsLocked -bool -DrawingEngine::IsLocked() -{ - return fGraphicsCard->IsWriteLocked(); -} - -// WriteLock -bool -DrawingEngine::WriteLock() -{ - return fGraphicsCard->WriteLock(); -} - -// WriteUnlock -void -DrawingEngine::WriteUnlock() -{ - fGraphicsCard->WriteUnlock(); -} - -// #pragma mark - - // DumpToFile bool DrawingEngine::DumpToFile(const char *path) { - if (Lock()) { - RenderingBuffer* buffer = fGraphicsCard->DrawingBuffer(); - if (buffer) { - BRect bounds(0.0, 0.0, buffer->Width() - 1, buffer->Height() - 1); - SaveToPNG(path, bounds, buffer->ColorSpace(), - buffer->Bits(), - buffer->BitsLength(), - buffer->BytesPerRow()); - } - Unlock(); - } - return true; + CRASH_IF_NOT_EXCLUSIVE_LOCKED + + RenderingBuffer* buffer = fGraphicsCard->DrawingBuffer(); + if (buffer) { + BRect bounds(0.0, 0.0, buffer->Width() - 1, buffer->Height() - 1); + SaveToPNG(path, bounds, buffer->ColorSpace(), + buffer->Bits(), + buffer->BitsLength(), + buffer->BytesPerRow()); + return true; + } + return false; } // DumpToBitmap @@ -1132,61 +1099,59 @@ DrawingEngine::DumpToBitmap() status_t DrawingEngine::ReadBitmap(ServerBitmap *bitmap, bool drawCursor, BRect bounds) { - if (Lock()) { - RenderingBuffer *buffer = fGraphicsCard->DrawingBuffer(); - if (!buffer) - return B_ERROR; + CRASH_IF_NOT_EXCLUSIVE_LOCKED - BRect clip(0, 0, buffer->Width() - 1, buffer->Height() - 1); - bounds = bounds & clip; - fGraphicsCard->HideSoftwareCursor(bounds); + RenderingBuffer *buffer = fGraphicsCard->DrawingBuffer(); + if (!buffer) + return B_ERROR; - status_t result = bitmap->ImportBits(buffer->Bits(), buffer->BitsLength(), - buffer->BytesPerRow(), buffer->ColorSpace(), - bounds.LeftTop(), BPoint(0, 0), - bounds.IntegerWidth() + 1, bounds.IntegerHeight() + 1); + BRect clip(0, 0, buffer->Width() - 1, buffer->Height() - 1); + bounds = bounds & clip; + fGraphicsCard->HideSoftwareCursor(bounds); - if (drawCursor) { - ServerCursor *cursor = fGraphicsCard->Cursor(); - int32 cursorWidth = cursor->Width(); - int32 cursorHeight = cursor->Height(); + status_t result = bitmap->ImportBits(buffer->Bits(), buffer->BitsLength(), + buffer->BytesPerRow(), buffer->ColorSpace(), + bounds.LeftTop(), BPoint(0, 0), + bounds.IntegerWidth() + 1, bounds.IntegerHeight() + 1); - BPoint cursorPosition = fGraphicsCard->CursorPosition(); - cursorPosition -= bounds.LeftTop() + cursor->GetHotSpot(); + if (drawCursor) { + ServerCursor *cursor = fGraphicsCard->Cursor(); + int32 cursorWidth = cursor->Width(); + int32 cursorHeight = cursor->Height(); - BBitmap cursorArea(BRect(0, 0, cursorWidth - 1, cursorHeight - 1), - B_BITMAP_NO_SERVER_LINK, B_RGBA32); - - cursorArea.ImportBits(bitmap->Bits(), bitmap->BitsLength(), - bitmap->BytesPerRow(), bitmap->ColorSpace(), - cursorPosition, BPoint(0, 0), - cursorWidth, cursorHeight); + BPoint cursorPosition = fGraphicsCard->CursorPosition(); + cursorPosition -= bounds.LeftTop() + cursor->GetHotSpot(); - uint8 *bits = (uint8 *)cursorArea.Bits(); - uint8 *cursorBits = (uint8 *)cursor->Bits(); - for (int32 i = 0; i < cursorHeight; i++) { - for (int32 j = 0; j < cursorWidth; j++) { - uint8 alpha = 255 - cursorBits[3]; - bits[0] = ((bits[0] * alpha) >> 8) + cursorBits[0]; - bits[1] = ((bits[1] * alpha) >> 8) + cursorBits[1]; - bits[2] = ((bits[2] * alpha) >> 8) + cursorBits[2]; - cursorBits += 4; - bits += 4; - } + BBitmap cursorArea(BRect(0, 0, cursorWidth - 1, cursorHeight - 1), + B_BITMAP_NO_SERVER_LINK, B_RGBA32); + + cursorArea.ImportBits(bitmap->Bits(), bitmap->BitsLength(), + bitmap->BytesPerRow(), bitmap->ColorSpace(), + cursorPosition, BPoint(0, 0), + cursorWidth, cursorHeight); + + uint8 *bits = (uint8 *)cursorArea.Bits(); + uint8 *cursorBits = (uint8 *)cursor->Bits(); + for (int32 i = 0; i < cursorHeight; i++) { + for (int32 j = 0; j < cursorWidth; j++) { + uint8 alpha = 255 - cursorBits[3]; + bits[0] = ((bits[0] * alpha) >> 8) + cursorBits[0]; + bits[1] = ((bits[1] * alpha) >> 8) + cursorBits[1]; + bits[2] = ((bits[2] * alpha) >> 8) + cursorBits[2]; + cursorBits += 4; + bits += 4; } - - bitmap->ImportBits(cursorArea.Bits(), cursorArea.BitsLength(), - cursorArea.BytesPerRow(), cursorArea.ColorSpace(), - BPoint(0, 0), cursorPosition, - cursorWidth, cursorHeight); } - fGraphicsCard->ShowSoftwareCursor(); - Unlock(); - return result; + bitmap->ImportBits(cursorArea.Bits(), cursorArea.BitsLength(), + cursorArea.BytesPerRow(), cursorArea.ColorSpace(), + BPoint(0, 0), cursorPosition, + cursorWidth, cursorHeight); } - return B_ERROR; + fGraphicsCard->ShowSoftwareCursor(); + + return result; } // #pragma mark - diff --git a/src/servers/app/drawing/DrawingEngine.h b/src/servers/app/drawing/DrawingEngine.h index ec5e7cf779..cbfe14a48a 100644 --- a/src/servers/app/drawing/DrawingEngine.h +++ b/src/servers/app/drawing/DrawingEngine.h @@ -44,17 +44,18 @@ public: // HWInterfaceListener interface virtual void FrameBufferChanged(); - // locking - bool Lock(); - void Unlock(); - bool IsLocked(); - - bool WriteLock(); - void WriteUnlock(); - // for "changing" hardware void SetHWInterface(HWInterface* interface); + // locking + bool LockParallelAccess(); + bool IsParallelAccessLocked(); + void UnlockParallelAccess(); + + bool LockExclusiveAccess(); + bool IsExclusiveAccessLocked(); + void UnlockExclusiveAccess(); + // for screen shots bool DumpToFile(const char *path); ServerBitmap* DumpToBitmap(); diff --git a/src/servers/app/drawing/HWInterface.cpp b/src/servers/app/drawing/HWInterface.cpp index 18b10dccf7..4f0d73fb44 100644 --- a/src/servers/app/drawing/HWInterface.cpp +++ b/src/servers/app/drawing/HWInterface.cpp @@ -30,6 +30,7 @@ HWInterfaceListener::~HWInterfaceListener() {} HWInterface::HWInterface(bool doubleBuffered) : MultiLocker("hw interface lock"), fCursorAreaBackup(NULL), + fSoftwareCursorLock("software cursor lock"), fCursor(NULL), fDragBitmap(NULL), fDragBitmapOffset(0, 0), @@ -78,74 +79,78 @@ HWInterface::GetDriverPath(BString &path) } -// SetCursor +// #pragma mark - + + void HWInterface::SetCursor(ServerCursor* cursor) { - if (WriteLock()) { - // TODO: if a bitmap is being dragged, it could - // be considered iritating to the user to change - // cursor shapes while something is dragged. - // The disabled code below would do this (except - // for the minor annoyance that the cursor is not - // updated when the drag is over) -// if (fDragBitmap) { -// // TODO: like a "+" or "-" sign when dragging some files to indicate -// // the current drag mode? -// WriteUnlock(); -// return; -// } - if (fCursor != cursor) { - BRect oldFrame = _CursorFrame(); + if (!fSoftwareCursorLock.Lock()) + return; - if (fCursorAndDragBitmap == fCursor) { - // make sure _AdoptDragBitmap doesn't delete a real cursor - fCursorAndDragBitmap = NULL; - } + // TODO: if a bitmap is being dragged, it could + // be considered iritating to the user to change + // cursor shapes while something is dragged. + // The disabled code below would prevent this (except + // for the minor annoyance that the cursor is not + // updated when the drag is over) +// if (fDragBitmap) { +// // TODO: like a "+" or "-" sign when dragging some files to indicate +// // the current drag mode? +// UnlockExclusiveAccess(); +// return; +// } + if (fCursor != cursor) { + BRect oldFrame = _CursorFrame(); - if (fCursor) - fCursor->Release(); - - fCursor = cursor; - - if (fCursor) - fCursor->Acquire(); - - Invalidate(oldFrame); - - _AdoptDragBitmap(fDragBitmap, fDragBitmapOffset); - Invalidate(_CursorFrame()); + if (fCursorAndDragBitmap == fCursor) { + // make sure _AdoptDragBitmap doesn't delete a real cursor + fCursorAndDragBitmap = NULL; } - WriteUnlock(); + + if (fCursor) + fCursor->Release(); + + fCursor = cursor; + + if (fCursor) + fCursor->Acquire(); + + Invalidate(oldFrame); + + _AdoptDragBitmap(fDragBitmap, fDragBitmapOffset); + Invalidate(_CursorFrame()); } + fSoftwareCursorLock.Unlock(); } // SetCursorVisible void HWInterface::SetCursorVisible(bool visible) { - if (WriteLock()) { - if (fCursorVisible != visible) { - // NOTE: _CursorFrame() will - // return an invalid rect if - // fCursorVisible == false! - if (visible) { - fCursorVisible = visible; - fCursorObscured = false; - BRect r = _CursorFrame(); + if (!fSoftwareCursorLock.Lock()) + return; - _DrawCursor(r); - Invalidate(r); - } else { - BRect r = _CursorFrame(); - fCursorVisible = visible; + if (fCursorVisible != visible) { + // NOTE: _CursorFrame() will + // return an invalid rect if + // fCursorVisible == false! + if (visible) { + fCursorVisible = visible; + fCursorObscured = false; + BRect r = _CursorFrame(); - _RestoreCursorArea(); - Invalidate(r); - } + _DrawCursor(r); + Invalidate(r); + } else { + BRect r = _CursorFrame(); + fCursorVisible = visible; + + _RestoreCursorArea(); + Invalidate(r); } - WriteUnlock(); } + fSoftwareCursorLock.Unlock(); } // IsCursorVisible @@ -153,9 +158,9 @@ bool HWInterface::IsCursorVisible() { bool visible = true; - if (ReadLock()) { + if (fSoftwareCursorLock.Lock()) { visible = fCursorVisible; - ReadUnlock(); + fSoftwareCursorLock.Unlock(); } return visible; } @@ -164,46 +169,46 @@ HWInterface::IsCursorVisible() void HWInterface::ObscureCursor() { - if (WriteLock()) { - if (!fCursorObscured) { - SetCursorVisible(false); - fCursorObscured = true; - } - WriteUnlock(); + if (!fSoftwareCursorLock.Lock()) + return; + + if (!fCursorObscured) { + SetCursorVisible(false); + fCursorObscured = true; } + fSoftwareCursorLock.Unlock(); } // MoveCursorTo void HWInterface::MoveCursorTo(const float& x, const float& y) { - if (WriteLock()) { - BPoint p(x, y); - if (p != fCursorLocation) { - // unhide cursor if it is obscured only - if (fCursorObscured) { - // TODO: causes nested lock, which - // the MultiLocker doesn't actually support? - SetCursorVisible(true); - } - BRect oldFrame = _CursorFrame(); - fCursorLocation = p; - if (fCursorVisible) { - // Invalidate and _DrawCursor would not draw - // anything if the cursor is hidden - // (invalid cursor frame), but explicitly - // testing for it here saves us some cycles - if (fCursorAreaBackup) { - // means we have a software cursor which we need to draw - _RestoreCursorArea(); - _DrawCursor(_CursorFrame()); - } - Invalidate(oldFrame); - Invalidate(_CursorFrame()); - } + if (!fSoftwareCursorLock.Lock()) + return; + + BPoint p(x, y); + if (p != fCursorLocation) { + // unhide cursor if it is obscured only + if (fCursorObscured) { + SetCursorVisible(true); + } + BRect oldFrame = _CursorFrame(); + fCursorLocation = p; + if (fCursorVisible) { + // Invalidate and _DrawCursor would not draw + // anything if the cursor is hidden + // (invalid cursor frame), but explicitly + // testing for it here saves us some cycles + if (fCursorAreaBackup) { + // means we have a software cursor which we need to draw + _RestoreCursorArea(); + _DrawCursor(_CursorFrame()); + } + Invalidate(oldFrame); + Invalidate(_CursorFrame()); } - WriteUnlock(); } + fSoftwareCursorLock.Unlock(); } @@ -211,25 +216,28 @@ BPoint HWInterface::CursorPosition() { BPoint location; - if (ReadLock()) { + if (fSoftwareCursorLock.Lock()) { location = fCursorLocation; - ReadUnlock(); + fSoftwareCursorLock.Unlock(); } return location; } -// SetDragBitmap + void HWInterface::SetDragBitmap(const ServerBitmap* bitmap, const BPoint& offsetFromCursor) { - if (WriteLock()) { + if (fSoftwareCursorLock.Lock()) { _AdoptDragBitmap(bitmap, offsetFromCursor); - WriteUnlock(); + fSoftwareCursorLock.Unlock(); } } -// DrawingBuffer + +// #pragma mark - + + RenderingBuffer* HWInterface::DrawingBuffer() const { @@ -238,14 +246,14 @@ HWInterface::DrawingBuffer() const return FrontBuffer(); } -// IsDoubleBuffered + bool HWInterface::IsDoubleBuffered() const { return fDoubleBuffered; } -// Invalidate + // * the object needs to be already locked! status_t HWInterface::Invalidate(const BRect& frame) @@ -269,7 +277,7 @@ HWInterface::Invalidate(const BRect& frame) return B_OK; } -// CopyBackToFront + // * the object must already be locked! status_t HWInterface::CopyBackToFront(const BRect& frame) @@ -370,7 +378,9 @@ HWInterface::HideSoftwareCursor(const BRect& area) fCursorAreaBackup->right, fCursorAreaBackup->bottom); if (area.Intersects(backupArea)) { + fSoftwareCursorLock.Lock(); _RestoreCursorArea(); + // do not unlock the cursor lock return true; } } @@ -381,6 +391,7 @@ HWInterface::HideSoftwareCursor(const BRect& area) void HWInterface::HideSoftwareCursor() { + fSoftwareCursorLock.Lock(); _RestoreCursorArea(); } @@ -391,6 +402,7 @@ HWInterface::ShowSoftwareCursor() if (fCursorAreaBackup && fCursorAreaBackup->cursor_hidden) { _DrawCursor(_CursorFrame()); } + fSoftwareCursorLock.Unlock(); } @@ -415,7 +427,7 @@ HWInterface::RemoveListener(HWInterfaceListener* listener) // #pragma mark - -// _DrawCursor + // * default implementation, can be used as fallback or for // software cursor // * area is where we potentially draw the cursor, the cursor @@ -433,6 +445,7 @@ HWInterface::_DrawCursor(BRect area) const area = backBuffer->Bounds() & area; if (cf.IsValid() && area.Intersects(cf)) { + // clip to common area area = area & cf; @@ -465,7 +478,8 @@ HWInterface::_DrawCursor(BRect area) const uint8* dst = buffer; - if (fCursorAreaBackup && fCursorAreaBackup->buffer) { + if (fCursorAreaBackup && fCursorAreaBackup->buffer + && fSoftwareCursorLock.Lock()) { fCursorAreaBackup->cursor_hidden = false; // remember which area the backup contains fCursorAreaBackup->left = left; @@ -501,6 +515,7 @@ HWInterface::_DrawCursor(BRect area) const dst += width * 4; bup += bupBPR; } + fSoftwareCursorLock.Unlock(); } else { // blending for (int32 y = top; y <= bottom; y++) { @@ -531,8 +546,7 @@ HWInterface::_DrawCursor(BRect area) const } } -// _CopyToFront -// + // * source is assumed to be already at the right offset // * source is assumed to be in B_RGBA32 format // * location in front buffer is calculated @@ -563,8 +577,7 @@ HWInterface::_CopyToFront(uint8* src, uint32 srcBPR, dst += dstBPR; src += srcBPR; } - } else -printf("nothing to copy\n"); + } break; } // NOTE: on R5, B_RGB24 bitmaps are not supported by DrawBitmap() @@ -679,8 +692,6 @@ printf("nothing to copy\n"); } -// _CursorFrame -// // PRE: the object must be locked BRect HWInterface::_CursorFrame() const @@ -693,7 +704,7 @@ HWInterface::_CursorFrame() const return frame; } -// _RestoreCursorArea + void HWInterface::_RestoreCursorArea() const { diff --git a/src/servers/app/drawing/HWInterface.h b/src/servers/app/drawing/HWInterface.h index b0e16daa50..6a9c5d16a4 100644 --- a/src/servers/app/drawing/HWInterface.h +++ b/src/servers/app/drawing/HWInterface.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -42,11 +43,20 @@ class HWInterfaceListener { virtual void FrameBufferChanged() = 0; }; -class HWInterface : public MultiLocker { +class HWInterface : protected MultiLocker { public: HWInterface(bool doubleBuffered = false); virtual ~HWInterface(); + // locking + bool LockParallelAccess() { return ReadLock(); } + bool IsParallelAccessLocked() { return IsReadLocked(); } + void UnlockParallelAccess() { ReadUnlock(); } + + bool LockExclusiveAccess() { return WriteLock(); } + bool IsExclusiveAccessLocked() { return IsWriteLocked(); } + void UnlockExclusiveAccess() { WriteUnlock(); } + // You need to WriteLock virtual status_t Initialize(); virtual status_t Shutdown() = 0; @@ -200,6 +210,7 @@ class HWInterface : public MultiLocker { }; buffer_clip* fCursorAreaBackup; + mutable BLocker fSoftwareCursorLock; ServerCursor* fCursor; const ServerBitmap* fDragBitmap; diff --git a/src/servers/app/drawing/Painter/Painter.cpp b/src/servers/app/drawing/Painter/Painter.cpp index 0833ea5ef4..9990a6311e 100644 --- a/src/servers/app/drawing/Painter/Painter.cpp +++ b/src/servers/app/drawing/Painter/Painter.cpp @@ -84,7 +84,7 @@ Painter::Painter() fSubpixelPrecise(false), fPenSize(1.0), - fClippingRegion(new BRegion()), + fClippingRegion(NULL), fValidClipping(false), fDrawingMode(B_OP_COPY), fDrawingText(false), @@ -96,7 +96,7 @@ Painter::Painter() fMiterLimit(B_DEFAULT_MITER_LIMIT), fPatternHandler(new PatternHandler()), - fTextRenderer(new AGGTextRenderer()) + fTextRenderer(AGGTextRenderer::Default()) { // Usually, the drawing engine will lock the font for us when // needed - unfortunately, it can't know we need it here @@ -114,9 +114,7 @@ Painter::~Painter() { _MakeEmpty(); - delete fClippingRegion; delete fPatternHandler; - delete fTextRenderer; } // #pragma mark - @@ -141,8 +139,6 @@ Painter::AttachToBuffer(RenderingBuffer* buffer) fPixelFormat->SetDrawingMode(fDrawingMode, fAlphaSrcMode, fAlphaFncMode, false); fBaseRenderer = new renderer_base(*fPixelFormat); - // attach our clipping region to the renderer, it keeps a pointer - fBaseRenderer->set_clipping_region(fClippingRegion); // These are the AGG renderes and rasterizes which // will be used for stroking paths @@ -234,17 +230,14 @@ Painter::SetDrawState(const DrawState* data, bool updateFont) void Painter::ConstrainClipping(const BRegion* region) { - *fClippingRegion = *region; - fValidClipping = fClippingRegion->Frame().IsValid(); + fClippingRegion = region; + fBaseRenderer->set_clipping_region(const_cast(region)); + fValidClipping = region->Frame().IsValid(); if (fValidClipping) { clipping_rect cb = fClippingRegion->FrameInt(); fRasterizer->clip_box(cb.left, cb.top, cb.right + 1, cb.bottom + 1); } -// TODO: would be nice if we didn't need to copy a region -// for *each* drawing command... -//fBaseRenderer->set_clipping_region(const_cast(region)); -//fValidClipping = region->Frame().IsValid(); } // SetHighColor diff --git a/src/servers/app/drawing/Painter/Painter.h b/src/servers/app/drawing/Painter/Painter.h index d0af13424c..490e3365f0 100644 --- a/src/servers/app/drawing/Painter/Painter.h +++ b/src/servers/app/drawing/Painter/Painter.h @@ -273,7 +273,7 @@ mutable agg::conv_curve fCurve; bool fSubpixelPrecise; float fPenSize; - BRegion* fClippingRegion; + const BRegion* fClippingRegion; bool fValidClipping; drawing_mode fDrawingMode; bool fDrawingText; diff --git a/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.cpp b/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.cpp index 8acafedabf..6cad2acb40 100644 --- a/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.cpp +++ b/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.cpp @@ -69,6 +69,10 @@ is_white_space(uint32 charCode) #define DEFAULT_UNI_CODE_BUFFER_SIZE 2048 +// init default instance +AGGTextRenderer +AGGTextRenderer::sDefaultInstance; + // constructor AGGTextRenderer::AGGTextRenderer() : fFontEngine(gFreeTypeLibrary), @@ -97,6 +101,13 @@ AGGTextRenderer::~AGGTextRenderer() free(fUnicodeBuffer); } +// Default +/*static*/ AGGTextRenderer* +AGGTextRenderer::Default() +{ + return &sDefaultInstance; +} + // SetFont bool AGGTextRenderer::SetFont(const ServerFont &font) diff --git a/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.h b/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.h index 7e334471cb..e26ba8c522 100644 --- a/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.h +++ b/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.h @@ -21,6 +21,14 @@ class AGGTextRenderer { AGGTextRenderer(); virtual ~AGGTextRenderer(); + // NOTE: every Painter instance is using the same + // AGGTextRenderer instance, and the only thing that + // protects locking is the fact that every use of a + // ServerFont goes through a global lock... this will + // have to be changed. Maybe every ServerFont should + // have it's own AGGTextRenderer or something + static AGGTextRenderer* Default(); + bool SetFont(const ServerFont &font); void Unset(); @@ -76,6 +84,8 @@ class AGGTextRenderer { bool fAntialias; bool fKerning; Transformable fEmbeddedTransformation; // rotated or sheared font? + + static AGGTextRenderer sDefaultInstance; }; #endif // AGG_TEXT_RENDERER_H diff --git a/src/servers/app/PatternHandler.h b/src/servers/app/drawing/PatternHandler.h similarity index 100% rename from src/servers/app/PatternHandler.h rename to src/servers/app/drawing/PatternHandler.h diff --git a/src/servers/app/drawing/UpdateQueue.cpp b/src/servers/app/drawing/UpdateQueue.cpp index a9c0657e80..5ff5fc4934 100644 --- a/src/servers/app/drawing/UpdateQueue.cpp +++ b/src/servers/app/drawing/UpdateQueue.cpp @@ -85,7 +85,7 @@ UpdateQueue::_ExecuteUpdates() case B_OK: case B_TIMED_OUT: // execute updates - if (fInterface->ReadLock()) { + if (fInterface->LockParallelAccess()) { int32 count = fUpdateRegion.CountRects(); if (count > 0) { for (int32 i = 0; i < count; i++) { @@ -93,7 +93,7 @@ UpdateQueue::_ExecuteUpdates() } fUpdateRegion.MakeEmpty(); } - fInterface->ReadUnlock(); + fInterface->UnlockParallelAccess(); } break; case B_BAD_SEM_ID: