* 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 {
|
||||
class ServerLink;
|
||||
class LinkReceiver;
|
||||
};
|
||||
|
||||
|
||||
/* Integer rect used to define a cliping rectangle. All bounds are included */
|
||||
/* Integer rect used to define a clipping rectangle. All bounds are inclusive. */
|
||||
/* Moved from DirectWindow.h */
|
||||
typedef struct {
|
||||
int32 left;
|
||||
@@ -71,6 +71,7 @@ private:
|
||||
friend class BDirectWindow;
|
||||
friend class Support;
|
||||
friend class BPrivate::ServerLink;
|
||||
friend class BPrivate::LinkReceiver;
|
||||
|
||||
void _AddRect(clipping_rect r);
|
||||
void set_size(long new_size);
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <OS.h>
|
||||
|
||||
class BString;
|
||||
class BRegion;
|
||||
|
||||
|
||||
namespace BPrivate {
|
||||
@@ -26,15 +27,16 @@ class LinkReceiver {
|
||||
void SetPort(port_id port);
|
||||
port_id Port(void) { return fReceivePort; }
|
||||
|
||||
status_t GetNextMessage(int32 &code, bigtime_t timeout = B_INFINITE_TIMEOUT);
|
||||
status_t GetNextMessage(int32& code, bigtime_t timeout = B_INFINITE_TIMEOUT);
|
||||
bool HasMessages() const;
|
||||
bool NeedsReply() const;
|
||||
int32 Code() const;
|
||||
|
||||
virtual status_t Read(void *data, ssize_t size);
|
||||
virtual status_t Read(void* data, ssize_t size);
|
||||
status_t ReadString(char** _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)
|
||||
{ return Read(data, sizeof(Type)); }
|
||||
@@ -46,7 +48,7 @@ class LinkReceiver {
|
||||
|
||||
port_id fReceivePort;
|
||||
|
||||
char *fRecvBuffer;
|
||||
char* fRecvBuffer;
|
||||
int32 fRecvPosition; //current read position
|
||||
int32 fRecvStart; //start of current message
|
||||
int32 fRecvBufferSize;
|
||||
|
||||
@@ -5,17 +5,20 @@
|
||||
* Authors:
|
||||
* Pahtz <[email protected]>
|
||||
* Axel Dörfler
|
||||
* Stephan Aßmus <[email protected]>
|
||||
*/
|
||||
|
||||
/** Class for low-overhead port-based messaging */
|
||||
|
||||
#include <LinkReceiver.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <new>
|
||||
|
||||
#include <ServerProtocol.h>
|
||||
#include <LinkReceiver.h>
|
||||
#include <String.h>
|
||||
#include <Region.h>
|
||||
|
||||
#include "link_message.h"
|
||||
|
||||
@@ -396,4 +399,22 @@ err:
|
||||
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
|
||||
|
||||
|
||||
|
||||
@@ -2714,19 +2714,12 @@ BView::FillRegion(BRegion *region, ::pattern pattern)
|
||||
|
||||
_UpdatePattern(pattern);
|
||||
|
||||
int32 count = region->CountRects();
|
||||
fOwner->fLink->StartMessage(AS_FILL_REGION);
|
||||
fOwner->fLink->AttachRegion(*region);
|
||||
// TODO: make this automatically chose
|
||||
// to send over area or handle failure here?
|
||||
|
||||
if (count * sizeof(BRect) < MAX_ATTACHMENT_SIZE) {
|
||||
fOwner->fLink->StartMessage(AS_FILL_REGION);
|
||||
fOwner->fLink->Attach<int32>(count);
|
||||
|
||||
for (int32 i = 0; i < count; i++)
|
||||
fOwner->fLink->Attach<BRect>(region->RectAt(i));
|
||||
|
||||
_FlushIfNotInTransaction();
|
||||
} else {
|
||||
// TODO: send via area
|
||||
}
|
||||
_FlushIfNotInTransaction();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -871,6 +871,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
if (link.Read<int32>(&token) != B_OK)
|
||||
break;
|
||||
|
||||
if (!fDesktop->GetCursorManager().Lock())
|
||||
break;
|
||||
|
||||
ServerCursor* oldCursor = fAppCursor;
|
||||
fAppCursor = fDesktop->GetCursorManager().FindCursor(token);
|
||||
if (fAppCursor != NULL)
|
||||
@@ -882,6 +885,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
if (oldCursor != NULL)
|
||||
oldCursor->Release();
|
||||
|
||||
fDesktop->GetCursorManager().Unlock();
|
||||
|
||||
if (sync) {
|
||||
// The application is expecting a reply
|
||||
fLink.StartMessage(B_OK);
|
||||
@@ -944,6 +949,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
if (link.Read<bool>(&pendingViewCursor) != B_OK)
|
||||
break;
|
||||
|
||||
if (!fDesktop->GetCursorManager().Lock())
|
||||
break;
|
||||
|
||||
ServerCursor* cursor = fDesktop->GetCursorManager().FindCursor(token);
|
||||
if (cursor) {
|
||||
if (pendingViewCursor)
|
||||
@@ -951,6 +959,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
|
||||
cursor->Release();
|
||||
}
|
||||
fDesktop->GetCursorManager().Unlock();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -1258,9 +1258,14 @@ ServerWindow::_DispatchViewMessage(int32 code,
|
||||
if (link.Read<bool>(&sync) != B_OK)
|
||||
break;
|
||||
|
||||
if (!fDesktop->GetCursorManager().Lock())
|
||||
break;
|
||||
|
||||
ServerCursor* cursor = fDesktop->GetCursorManager().FindCursor(token);
|
||||
fCurrentLayer->SetCursor(cursor);
|
||||
|
||||
fDesktop->GetCursorManager().Unlock();
|
||||
|
||||
if (fWindowLayer->IsFocus()) {
|
||||
// The cursor might need to be updated now
|
||||
if (fDesktop->ViewUnderMouse(fWindowLayer) == fCurrentLayer->Token())
|
||||
@@ -1603,6 +1608,7 @@ ServerWindow::_DispatchViewMessage(int32 code,
|
||||
status = link.Read<clipping_rect>(&r);
|
||||
if (status < B_OK)
|
||||
break;
|
||||
// TODO: optimize (use AttachRegion()+ReadRegion())
|
||||
region.Include(r);
|
||||
}
|
||||
} else
|
||||
@@ -2096,30 +2102,13 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
|
||||
{
|
||||
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;
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
region.Include(rects[i]);
|
||||
}
|
||||
if (link.ReadRegion(®ion) < B_OK)
|
||||
break;
|
||||
|
||||
fCurrentLayer->ConvertToScreenForDrawing(®ion);
|
||||
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;
|
||||
}
|
||||
case AS_STROKE_LINEARRAY:
|
||||
|
||||
Reference in New Issue
Block a user