* renamed HWInterface locking to LockParallelAccess() and

LockExclusiveAccess() (meaning more or less access to the
  frame buffer)
* extracted the AGGTextRenderer to be a global instance used
  by each Painter instance (currently, it is thread safe because
  of the global font lock, so there is some work left in this
  regard)
* gave every ServerWindow it's own DrawingEngine instance, this
  is work in progress. So far, there doesn't seem to be a regression,
  but less fighting over the exclusive access to the frame buffer, now
  each ServerWindow thread can draw in parallel. There is room for
  improvement, plus I think I'm leaking the DrawingEngine...
* changed the locking for the software cursor. ShowSoftwareCursor()
  can only be called if HideSoftwareCursor(BRect) returned true, or
  if you called the generic HideSoftwareCursor(), since it needs
  to keep the cursor lock and unlocks in Show...!
* some clean up and renaming in Decorator and friends
* moved PatternHandler.h to live along with the .cpp


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19427 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2006-12-04 22:25:17 +00:00
parent c31e5df06c
commit 2cfe93e780
23 changed files with 819 additions and 786 deletions
+4 -4
View File
@@ -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
+1 -1
View File
@@ -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;
+39 -39
View File
@@ -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;
+12 -10
View File
@@ -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;
+143 -143
View File
@@ -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);
+2 -2
View File
@@ -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();
}
}
}
+1
View File
@@ -10,6 +10,7 @@ UseFreeTypeHeaders ;
Server app_server :
Angle.cpp
AppServer.cpp
BitfieldRegion.cpp
BitmapManager.cpp
ClientMemoryAllocator.cpp
CursorData.cpp
+10 -2
View File
@@ -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()
{
Unlock();
}
void Unlock()
{
if (fLocked) {
fLock.ReadUnlock();
fLocked = false;
}
}
private:
MultiLocker& fLock;
bool fLocked;
};
+2 -2
View File
@@ -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;
}
+7 -8
View File
@@ -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
+6 -1
View File
@@ -1354,7 +1354,12 @@ ViewLayer::AddTokensForLayersInRegion(BPrivate::PortLink& link,
if (!fVisible)
return;
if (region.Intersects(ScreenClipping(windowContentClipping).Frame()))
// if (region.Intersects(ScreenClipping(windowContentClipping).Frame()))
IntRect screenBounds(Bounds());
ConvertToScreen(&screenBounds);
if (!region.Intersects((clipping_rect)screenBounds))
return;
link.Attach<int32>(fToken);
for (ViewLayer* child = FirstChild(); child; child = child->NextSibling())
+33 -17
View File
@@ -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<int32>(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);
@@ -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();
// }
}
+85 -120
View File
@@ -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,13 +316,11 @@ 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()) {
CRASH_IF_NOT_EXCLUSIVE_LOCKED
BRect frame = region->Frame();
frame = frame | frame.OffsetByCopy(xOffset, yOffset);
fGraphicsCard->HideSoftwareCursor(frame);
bool cursorTouched = fGraphicsCard->HideSoftwareCursor(frame);
int32 count = region->CountRects();
@@ -389,24 +424,20 @@ DrawingEngine::CopyRegion(/*const*/ BRegion* region,
delete[] sortedRectList;
if (cursorTouched)
fGraphicsCard->ShowSoftwareCursor();
WriteUnlock();
}
}
// 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()) {
CRASH_IF_NOT_LOCKED
make_rect_valid(r);
r = fPainter->ClipRect(r);
if (r.IsValid()) {
fGraphicsCard->HideSoftwareCursor(r);
bool cursorTouched = fGraphicsCard->HideSoftwareCursor(r);
// try hardware optimized version first
if (fAvailableHWAccleration & HW_ACC_INVERT_REGION) {
@@ -419,11 +450,9 @@ DrawingEngine::InvertRect(BRect r)
fGraphicsCard->Invalidate(r);
}
if (cursorTouched)
fGraphicsCard->ShowSoftwareCursor();
}
WriteUnlock();
}
}
// DrawBitmap
@@ -436,12 +465,13 @@ 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);
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,6 +505,7 @@ DrawingEngine::DrawArc(BRect r, const float &angle,
fPainter->StrokeArc(center, xRadius, yRadius, angle, span);
fGraphicsCard->Invalidate(clipped);
if (cursorTouched)
fGraphicsCard->ShowSoftwareCursor();
}
}
@@ -516,12 +547,13 @@ 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);
if (cursorTouched)
fGraphicsCard->ShowSoftwareCursor();
}
}
@@ -539,12 +571,13 @@ 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);
if (cursorTouched)
fGraphicsCard->ShowSoftwareCursor();
}
}
@@ -562,15 +595,15 @@ 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);
bool cursorTouched = fGraphicsCard->HideSoftwareCursor(touched);
if (!fPainter->StraightLine(start, end, color.GetColor32())) {
DrawState context;
@@ -580,9 +613,8 @@ DrawingEngine::StrokeLine(const BPoint &start, const BPoint &end, const RGBColor
} else {
fGraphicsCard->Invalidate(touched);
}
if (cursorTouched)
fGraphicsCard->ShowSoftwareCursor();
Unlock();
}
}
// this function is used to draw a one pixel wide rect
@@ -591,20 +623,17 @@ 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);
bool cursorTouched = fGraphicsCard->HideSoftwareCursor(clipped);
fPainter->StrokeRect(r, color.GetColor32());
fGraphicsCard->Invalidate(clipped);
if (cursorTouched)
fGraphicsCard->ShowSoftwareCursor();
}
Unlock();
}
}
@@ -616,7 +645,6 @@ 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()) {
@@ -638,9 +666,6 @@ DrawingEngine::FillRect(BRect r, const RGBColor& color)
if (cursorTouched)
fGraphicsCard->ShowSoftwareCursor();
}
WriteUnlock();
}
}
@@ -649,11 +674,7 @@ 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);
@@ -678,9 +699,6 @@ DrawingEngine::FillRegion(BRegion& r, const RGBColor& color)
if (cursorTouched)
fGraphicsCard->ShowSoftwareCursor();
WriteUnlock();
}
}
// #pragma mark - DrawState
@@ -697,12 +715,13 @@ 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);
if (cursorTouched)
fGraphicsCard->ShowSoftwareCursor();
}
}
@@ -713,10 +732,6 @@ 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()) {
@@ -757,9 +772,6 @@ DrawingEngine::FillRect(BRect r, const DrawState *d)
if (cursorTouched)
fGraphicsCard->ShowSoftwareCursor();
}
WriteUnlock();
}
}
@@ -768,10 +780,6 @@ 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);
@@ -813,9 +821,6 @@ DrawingEngine::FillRegion(BRegion& r, const DrawState *d)
if (cursorTouched)
fGraphicsCard->ShowSoftwareCursor();
}
WriteUnlock();
}
}
@@ -836,13 +841,14 @@ 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);
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,6 +895,7 @@ DrawingEngine::DrawTriangle(BPoint* pts, const BRect& bounds,
fPainter->StrokeTriangle(pts[0], pts[1], pts[2]);
fGraphicsCard->Invalidate(clipped);
if (cursorTouched)
fGraphicsCard->ShowSoftwareCursor();
}
}
@@ -904,12 +911,13 @@ 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);
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,6 +972,7 @@ DrawingEngine::StrokeLineArray(int32 numLines,
}
fGraphicsCard->Invalidate(touched);
if (cursorTouched)
fGraphicsCard->ShowSoftwareCursor();
}
}
@@ -996,13 +1005,14 @@ 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);
if (cursorTouched)
fGraphicsCard->ShowSoftwareCursor();
}
@@ -1018,7 +1028,6 @@ 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
@@ -1026,8 +1035,6 @@ DrawingEngine::StringWidth(const char* string, int32 length,
// 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();
// }
return width;
}
@@ -1049,7 +1056,6 @@ 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
@@ -1060,55 +1066,17 @@ DrawingEngine::StringHeight(const char *string, int32 length,
BPoint dummy1(0.0, 0.0);
BPoint dummy2(0.0, 0.0);
height = fPainter->BoundingBox(string, length, dummy1, &dummy2).Height();
// Unlock();
// }
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()) {
CRASH_IF_NOT_EXCLUSIVE_LOCKED
RenderingBuffer* buffer = fGraphicsCard->DrawingBuffer();
if (buffer) {
BRect bounds(0.0, 0.0, buffer->Width() - 1, buffer->Height() - 1);
@@ -1116,11 +1084,10 @@ DrawingEngine::DumpToFile(const char *path)
buffer->Bits(),
buffer->BitsLength(),
buffer->BytesPerRow());
}
Unlock();
}
return true;
}
return false;
}
// DumpToBitmap
ServerBitmap*
@@ -1132,7 +1099,8 @@ DrawingEngine::DumpToBitmap()
status_t
DrawingEngine::ReadBitmap(ServerBitmap *bitmap, bool drawCursor, BRect bounds)
{
if (Lock()) {
CRASH_IF_NOT_EXCLUSIVE_LOCKED
RenderingBuffer *buffer = fGraphicsCard->DrawingBuffer();
if (!buffer)
return B_ERROR;
@@ -1182,11 +1150,8 @@ DrawingEngine::ReadBitmap(ServerBitmap *bitmap, bool drawCursor, BRect bounds)
}
fGraphicsCard->ShowSoftwareCursor();
Unlock();
return result;
}
return B_ERROR;
return result;
}
// #pragma mark -
+9 -8
View File
@@ -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();
+48 -37
View File
@@ -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,21 +79,25 @@ HWInterface::GetDriverPath(BString &path)
}
// SetCursor
// #pragma mark -
void
HWInterface::SetCursor(ServerCursor* cursor)
{
if (WriteLock()) {
if (!fSoftwareCursorLock.Lock())
return;
// 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
// 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?
// WriteUnlock();
// UnlockExclusiveAccess();
// return;
// }
if (fCursor != cursor) {
@@ -116,15 +121,16 @@ HWInterface::SetCursor(ServerCursor* cursor)
_AdoptDragBitmap(fDragBitmap, fDragBitmapOffset);
Invalidate(_CursorFrame());
}
WriteUnlock();
}
fSoftwareCursorLock.Unlock();
}
// SetCursorVisible
void
HWInterface::SetCursorVisible(bool visible)
{
if (WriteLock()) {
if (!fSoftwareCursorLock.Lock())
return;
if (fCursorVisible != visible) {
// NOTE: _CursorFrame() will
// return an invalid rect if
@@ -144,8 +150,7 @@ HWInterface::SetCursorVisible(bool visible)
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,26 +169,27 @@ HWInterface::IsCursorVisible()
void
HWInterface::ObscureCursor()
{
if (WriteLock()) {
if (!fSoftwareCursorLock.Lock())
return;
if (!fCursorObscured) {
SetCursorVisible(false);
fCursorObscured = true;
}
WriteUnlock();
}
fSoftwareCursorLock.Unlock();
}
// MoveCursorTo
void
HWInterface::MoveCursorTo(const float& x, const float& y)
{
if (WriteLock()) {
if (!fSoftwareCursorLock.Lock())
return;
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();
@@ -202,8 +208,7 @@ HWInterface::MoveCursorTo(const float& x, const float& y)
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
{
+12 -1
View File
@@ -16,6 +16,7 @@
#include <Accelerant.h>
#include <GraphicsCard.h>
#include <List.h>
#include <Locker.h>
#include <OS.h>
#include <Region.h>
@@ -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;
+5 -12
View File
@@ -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<BRegion*>(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<BRegion*>(region));
//fValidClipping = region->Frame().IsValid();
}
// SetHighColor
+1 -1
View File
@@ -273,7 +273,7 @@ mutable agg::conv_curve<agg::path_storage> fCurve;
bool fSubpixelPrecise;
float fPenSize;
BRegion* fClippingRegion;
const BRegion* fClippingRegion;
bool fValidClipping;
drawing_mode fDrawingMode;
bool fDrawingText;
@@ -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)
@@ -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
+2 -2
View File
@@ -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: