* BView::FillRegion() sends the BRegion data instead of decomposing
it and rebuilding it on the server side (that causes a huge speed up for regions containing many rects) * There is a method in ServerLink that could have been used, but I actually needed to add the direct BRegion support to LinkReceiver * added LinkReceiver as a friend to BRegion class * ServerApp and ServerWindow keep the CursorManager locked after they have retrieved a cursor until they have called Acquire() on the cursor. (Axel: what good is using atomic* stuff in Acquire() and Release() if we have to protect this by a lock anyways?) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16957 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -17,10 +17,10 @@
|
|||||||
|
|
||||||
namespace BPrivate {
|
namespace BPrivate {
|
||||||
class ServerLink;
|
class ServerLink;
|
||||||
|
class LinkReceiver;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Integer rect used to define a clipping rectangle. All bounds are inclusive. */
|
||||||
/* Integer rect used to define a cliping rectangle. All bounds are included */
|
|
||||||
/* Moved from DirectWindow.h */
|
/* Moved from DirectWindow.h */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32 left;
|
int32 left;
|
||||||
@@ -71,6 +71,7 @@ private:
|
|||||||
friend class BDirectWindow;
|
friend class BDirectWindow;
|
||||||
friend class Support;
|
friend class Support;
|
||||||
friend class BPrivate::ServerLink;
|
friend class BPrivate::ServerLink;
|
||||||
|
friend class BPrivate::LinkReceiver;
|
||||||
|
|
||||||
void _AddRect(clipping_rect r);
|
void _AddRect(clipping_rect r);
|
||||||
void set_size(long new_size);
|
void set_size(long new_size);
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include <OS.h>
|
#include <OS.h>
|
||||||
|
|
||||||
class BString;
|
class BString;
|
||||||
|
class BRegion;
|
||||||
|
|
||||||
|
|
||||||
namespace BPrivate {
|
namespace BPrivate {
|
||||||
@@ -35,6 +36,7 @@ class LinkReceiver {
|
|||||||
status_t ReadString(char** _string, size_t* _length = NULL);
|
status_t ReadString(char** _string, size_t* _length = NULL);
|
||||||
status_t ReadString(BString& string, size_t* _length = NULL);
|
status_t ReadString(BString& string, size_t* _length = NULL);
|
||||||
status_t ReadString(char* buffer, size_t bufferSize);
|
status_t ReadString(char* buffer, size_t bufferSize);
|
||||||
|
status_t ReadRegion(BRegion* region);
|
||||||
|
|
||||||
template <class Type> status_t Read(Type *data)
|
template <class Type> status_t Read(Type *data)
|
||||||
{ return Read(data, sizeof(Type)); }
|
{ return Read(data, sizeof(Type)); }
|
||||||
|
|||||||
@@ -5,17 +5,20 @@
|
|||||||
* Authors:
|
* Authors:
|
||||||
* Pahtz <[email protected]>
|
* Pahtz <[email protected]>
|
||||||
* Axel Dörfler
|
* Axel Dörfler
|
||||||
|
* Stephan Aßmus <[email protected]>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** Class for low-overhead port-based messaging */
|
/** Class for low-overhead port-based messaging */
|
||||||
|
|
||||||
|
#include <LinkReceiver.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <new>
|
#include <new>
|
||||||
|
|
||||||
#include <ServerProtocol.h>
|
#include <ServerProtocol.h>
|
||||||
#include <LinkReceiver.h>
|
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
|
#include <Region.h>
|
||||||
|
|
||||||
#include "link_message.h"
|
#include "link_message.h"
|
||||||
|
|
||||||
@@ -396,4 +399,22 @@ err:
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
LinkReceiver::ReadRegion(BRegion* region)
|
||||||
|
{
|
||||||
|
status_t status = Read(®ion->count, sizeof(int32));
|
||||||
|
if (status >= B_OK)
|
||||||
|
status = Read(®ion->bound, sizeof(clipping_rect));
|
||||||
|
if (status >= B_OK) {
|
||||||
|
region->set_size(region->count);
|
||||||
|
status = Read(region->data, region->count * sizeof(clipping_rect));
|
||||||
|
if (status < B_OK)
|
||||||
|
region->MakeEmpty();
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace BPrivate
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2714,19 +2714,12 @@ BView::FillRegion(BRegion *region, ::pattern pattern)
|
|||||||
|
|
||||||
_UpdatePattern(pattern);
|
_UpdatePattern(pattern);
|
||||||
|
|
||||||
int32 count = region->CountRects();
|
|
||||||
|
|
||||||
if (count * sizeof(BRect) < MAX_ATTACHMENT_SIZE) {
|
|
||||||
fOwner->fLink->StartMessage(AS_FILL_REGION);
|
fOwner->fLink->StartMessage(AS_FILL_REGION);
|
||||||
fOwner->fLink->Attach<int32>(count);
|
fOwner->fLink->AttachRegion(*region);
|
||||||
|
// TODO: make this automatically chose
|
||||||
for (int32 i = 0; i < count; i++)
|
// to send over area or handle failure here?
|
||||||
fOwner->fLink->Attach<BRect>(region->RectAt(i));
|
|
||||||
|
|
||||||
_FlushIfNotInTransaction();
|
_FlushIfNotInTransaction();
|
||||||
} else {
|
|
||||||
// TODO: send via area
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -871,6 +871,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
if (link.Read<int32>(&token) != B_OK)
|
if (link.Read<int32>(&token) != B_OK)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (!fDesktop->GetCursorManager().Lock())
|
||||||
|
break;
|
||||||
|
|
||||||
ServerCursor* oldCursor = fAppCursor;
|
ServerCursor* oldCursor = fAppCursor;
|
||||||
fAppCursor = fDesktop->GetCursorManager().FindCursor(token);
|
fAppCursor = fDesktop->GetCursorManager().FindCursor(token);
|
||||||
if (fAppCursor != NULL)
|
if (fAppCursor != NULL)
|
||||||
@@ -882,6 +885,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
if (oldCursor != NULL)
|
if (oldCursor != NULL)
|
||||||
oldCursor->Release();
|
oldCursor->Release();
|
||||||
|
|
||||||
|
fDesktop->GetCursorManager().Unlock();
|
||||||
|
|
||||||
if (sync) {
|
if (sync) {
|
||||||
// The application is expecting a reply
|
// The application is expecting a reply
|
||||||
fLink.StartMessage(B_OK);
|
fLink.StartMessage(B_OK);
|
||||||
@@ -944,6 +949,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
if (link.Read<bool>(&pendingViewCursor) != B_OK)
|
if (link.Read<bool>(&pendingViewCursor) != B_OK)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (!fDesktop->GetCursorManager().Lock())
|
||||||
|
break;
|
||||||
|
|
||||||
ServerCursor* cursor = fDesktop->GetCursorManager().FindCursor(token);
|
ServerCursor* cursor = fDesktop->GetCursorManager().FindCursor(token);
|
||||||
if (cursor) {
|
if (cursor) {
|
||||||
if (pendingViewCursor)
|
if (pendingViewCursor)
|
||||||
@@ -951,6 +959,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
|
|
||||||
cursor->Release();
|
cursor->Release();
|
||||||
}
|
}
|
||||||
|
fDesktop->GetCursorManager().Unlock();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1258,9 +1258,14 @@ ServerWindow::_DispatchViewMessage(int32 code,
|
|||||||
if (link.Read<bool>(&sync) != B_OK)
|
if (link.Read<bool>(&sync) != B_OK)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (!fDesktop->GetCursorManager().Lock())
|
||||||
|
break;
|
||||||
|
|
||||||
ServerCursor* cursor = fDesktop->GetCursorManager().FindCursor(token);
|
ServerCursor* cursor = fDesktop->GetCursorManager().FindCursor(token);
|
||||||
fCurrentLayer->SetCursor(cursor);
|
fCurrentLayer->SetCursor(cursor);
|
||||||
|
|
||||||
|
fDesktop->GetCursorManager().Unlock();
|
||||||
|
|
||||||
if (fWindowLayer->IsFocus()) {
|
if (fWindowLayer->IsFocus()) {
|
||||||
// The cursor might need to be updated now
|
// The cursor might need to be updated now
|
||||||
if (fDesktop->ViewUnderMouse(fWindowLayer) == fCurrentLayer->Token())
|
if (fDesktop->ViewUnderMouse(fWindowLayer) == fCurrentLayer->Token())
|
||||||
@@ -1603,6 +1608,7 @@ ServerWindow::_DispatchViewMessage(int32 code,
|
|||||||
status = link.Read<clipping_rect>(&r);
|
status = link.Read<clipping_rect>(&r);
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
break;
|
break;
|
||||||
|
// TODO: optimize (use AttachRegion()+ReadRegion())
|
||||||
region.Include(r);
|
region.Include(r);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
@@ -2096,30 +2102,13 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
|
|||||||
{
|
{
|
||||||
DTRACE(("ServerWindow %s: Message AS_FILL_REGION\n", Title()));
|
DTRACE(("ServerWindow %s: Message AS_FILL_REGION\n", Title()));
|
||||||
|
|
||||||
int32 count;
|
|
||||||
link.Read<int32>(&count);
|
|
||||||
|
|
||||||
BRect* rects = new(nothrow) BRect[count];
|
|
||||||
if (link.Read(rects, sizeof(BRect) * count) < B_OK) {
|
|
||||||
delete[] rects;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Between the client-side conversion to BRects from clipping_rects to the overhead
|
|
||||||
// in repeatedly calling FillRect(), this is definitely in need of optimization. At
|
|
||||||
// least it works for now. :)
|
|
||||||
BRegion region;
|
BRegion region;
|
||||||
for (int32 i = 0; i < count; i++) {
|
if (link.ReadRegion(®ion) < B_OK)
|
||||||
region.Include(rects[i]);
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
fCurrentLayer->ConvertToScreenForDrawing(®ion);
|
fCurrentLayer->ConvertToScreenForDrawing(®ion);
|
||||||
drawingEngine->FillRegion(region, fCurrentLayer->CurrentState());
|
drawingEngine->FillRegion(region, fCurrentLayer->CurrentState());
|
||||||
|
|
||||||
delete[] rects;
|
|
||||||
|
|
||||||
// TODO: create support for clipping_rect usage for faster BRegion display.
|
|
||||||
// Tweaks to DrawingEngine are necessary along with conversion routines in ViewLayer
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AS_STROKE_LINEARRAY:
|
case AS_STROKE_LINEARRAY:
|
||||||
|
|||||||
Reference in New Issue
Block a user