Begun to use structs for the BView<->app_server communication. This makes

the protocoll less prone to errors, reduces possible points of failure and
most importantly, reduces the number of function calls to the link API.
I only know the numbers for StrokeLine(), which I tested via the Benchmark
test app. With this change, drawing random colored and positioned lines
actually doubled in speed. On the BView side, the calls to
ServerLink::Attach() only halfed, while on the app_server side, the number
of calls to ServerLink::Read() is now 1/4th. It will also be worth
investigating why the link stuff is so slow at all. I also optimized
BView::DrawString() a lot in this change, but I don't have any numbers
yet. Some other commands which used multiple Attach()/Read() calls were
also optimized, at least the most important ones. Begin/EndLineArray() was
also pretty bad on the app_server side. 


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29937 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2009-04-05 14:59:43 +00:00
parent a6354157ca
commit 12349c7d3d
7 changed files with 360 additions and 369 deletions

View File

@ -15,6 +15,7 @@
#include <Point.h>
#include <Rect.h>
#include <Region.h>
#include <ServerProtocolStructs.h>
const static uint32 kDeleteReplicant = 'JAHA';
@ -121,21 +122,13 @@ ViewState::IsAllValid() const
} // namespace BPrivate
struct _array_hdr_{
float startX;
float startY;
float endX;
float endY;
rgb_color color;
};
struct _array_data_{
// the max number of points in the array
uint32 maxCount;
uint32 maxCount;
// the current number of points in the array
uint32 count;
uint32 count;
// the array of points
_array_hdr_* array;
ViewLineArrayInfo* array;
};
#endif /* VIEW_PRIVATE_H */

View File

@ -51,6 +51,7 @@
#include <MessageUtils.h>
#include <PortLink.h>
#include <ServerProtocol.h>
#include <ServerProtocolStructs.h>
#include <ShapePrivate.h>
#include <TokenSpace.h>
#include <ViewPrivate.h>
@ -216,22 +217,27 @@ ViewState::UpdateServerState(BPrivate::PortLink &link)
UpdateServerFontState(link);
link.StartMessage(AS_VIEW_SET_STATE);
link.Attach<BPoint>(pen_location);
link.Attach<float>(pen_size);
link.Attach<rgb_color>(high_color);
link.Attach<rgb_color>(low_color);
link.Attach< ::pattern>(pattern);
link.Attach<int8>((int8)drawing_mode);
link.Attach<BPoint>(origin);
link.Attach<int8>((int8)line_join);
link.Attach<int8>((int8)line_cap);
link.Attach<float>(miter_limit);
link.Attach<int8>((int8)alpha_source_mode);
link.Attach<int8>((int8)alpha_function_mode);
link.Attach<float>(scale);
link.Attach<bool>(font_aliasing);
ViewSetStateInfo info;
info.penLocation = pen_location;
info.penSize = pen_size;
info.highColor = high_color;
info.lowColor = low_color;
info.pattern = pattern;
info.drawingMode = drawing_mode;
info.origin = origin;
info.scale = scale;
info.lineJoin = line_join;
info.lineCap = line_cap;
info.miterLimit = miter_limit;
info.alphaSourceMode = alpha_source_mode;
info.alphaFunctionMode = alpha_function_mode;
info.fontAntialiasing = font_aliasing;
link.Attach<ViewSetStateInfo>(info);
// we send the 'local' clipping region... if we have one...
// TODO: Could be optimized, but is low prio, since most views won't
// have a custom clipping region.
if (clipping_region_used) {
int32 count = clipping_region.CountRects();
link.Attach<int32>(count);
@ -260,57 +266,36 @@ ViewState::UpdateFrom(BPrivate::PortLink &link)
|| code != B_OK)
return;
uint32 fontID;
float size;
float shear;
float rotation;
float falseBoldeWidth;
uint8 spacing;
uint8 encoding;
uint16 face;
uint32 flags;
// read and set the font state
link.Read<int32>((int32 *)&fontID);
link.Read<float>(&size);
link.Read<float>(&shear);
link.Read<float>(&rotation);
link.Read<float>(&falseBoldeWidth);
link.Read<int8>((int8 *)&spacing);
link.Read<int8>((int8 *)&encoding);
link.Read<int16>((int16 *)&face);
link.Read<int32>((int32 *)&flags);
ViewGetStateInfo info;
link.Read<ViewGetStateInfo>(&info);
// set view's font state
font_flags = B_FONT_ALL;
font.SetFamilyAndStyle(fontID);
font.SetSize(size);
font.SetShear(shear);
font.SetRotation(rotation);
font.SetFalseBoldWidth(falseBoldeWidth);
font.SetSpacing(spacing);
font.SetEncoding(encoding);
font.SetFace(face);
font.SetFlags(flags);
font.SetFamilyAndStyle(info.fontID);
font.SetSize(info.fontSize);
font.SetShear(info.fontShear);
font.SetRotation(info.fontRotation);
font.SetFalseBoldWidth(info.fontFalseBoldWidth);
font.SetSpacing(info.fontSpacing);
font.SetEncoding(info.fontEncoding);
font.SetFace(info.fontFace);
font.SetFlags(info.fontFlags);
// read and set view's state
link.Read<BPoint>(&pen_location);
link.Read<float>(&pen_size);
link.Read<rgb_color>(&high_color);
link.Read<rgb_color>(&low_color);
link.Read< ::pattern>(&pattern);
link.Read<BPoint>(&origin);
int8 drawingMode;
link.Read<int8>((int8 *)&drawingMode);
drawing_mode = (::drawing_mode)drawingMode;
link.Read<int8>((int8 *)&line_cap);
link.Read<int8>((int8 *)&line_join);
link.Read<float>(&miter_limit);
link.Read<int8>((int8 *)&alpha_source_mode);
link.Read<int8>((int8 *)&alpha_function_mode);
link.Read<float>(&scale);
link.Read<bool>(&font_aliasing);
// set view's state
pen_location = info.viewStateInfo.penLocation;
pen_size = info.viewStateInfo.penSize;
high_color = info.viewStateInfo.highColor;
low_color = info.viewStateInfo.lowColor;
pattern = info.viewStateInfo.pattern;
drawing_mode = info.viewStateInfo.drawingMode;
origin = info.viewStateInfo.origin;
scale = info.viewStateInfo.scale;
line_join = info.viewStateInfo.lineJoin;
line_cap = info.viewStateInfo.lineCap;
miter_limit = info.viewStateInfo.miterLimit;
alpha_source_mode = info.viewStateInfo.alphaSourceMode;
alpha_function_mode = info.viewStateInfo.alphaFunctionMode;
font_aliasing = info.viewStateInfo.fontAntialiasing;
// read the user clipping
// (that's NOT the current View visible clipping but the additional
@ -796,6 +781,7 @@ BView::_ConvertFromScreen(BPoint *pt, bool checkLock) const
fParent->_ConvertFromScreen(pt, false);
}
void
BView::ConvertFromScreen(BPoint *pt) const
{
@ -1017,8 +1003,10 @@ BView::SetViewCursor(const BCursor *cursor, bool sync)
_CheckLockAndSwitchCurrent();
fOwner->fLink->StartMessage(AS_VIEW_SET_CURSOR);
fOwner->fLink->Attach<int32>(cursor->fServerToken);
fOwner->fLink->Attach<bool>(sync);
ViewSetViewCursorInfo info;
info.cursorToken = cursor->fServerToken;
info.sync = sync;
fOwner->fLink->Attach<ViewSetViewCursorInfo>(info);
if (!sync) {
cursor->fPendingViewCursor = true;
@ -1781,10 +1769,13 @@ BView::SetLineMode(cap_mode lineCap, join_mode lineJoin, float miterLimit)
if (fOwner) {
_CheckLockAndSwitchCurrent();
ViewSetLineModeInfo info;
info.lineJoin = lineJoin;
info.lineCap = lineCap;
info.miterLimit = miterLimit;
fOwner->fLink->StartMessage(AS_VIEW_SET_LINE_MODE);
fOwner->fLink->Attach<int8>((int8)lineCap);
fOwner->fLink->Attach<int8>((int8)lineJoin);
fOwner->fLink->Attach<float>(miterLimit);
fOwner->fLink->Attach<ViewSetLineModeInfo>(info);
fState->valid_flags |= B_VIEW_LINE_MODES_BIT;
}
@ -1830,13 +1821,13 @@ BView::LineMiterLimit() const
int32 code;
if (fOwner->fLink->FlushWithReply(code) == B_OK
&& code == B_OK) {
int8 cap, join;
fOwner->fLink->Read<int8>((int8 *)&cap);
fOwner->fLink->Read<int8>((int8 *)&join);
fOwner->fLink->Read<float>(&fState->miter_limit);
fState->line_cap = (cap_mode)cap;
fState->line_join = (join_mode)join;
ViewSetLineModeInfo info;
fOwner->fLink->Read<ViewSetLineModeInfo>(&info);
fState->line_cap = info.lineCap;
fState->line_join = info.lineJoin;
fState->miter_limit = info.miterLimit;
}
fState->valid_flags |= B_VIEW_LINE_MODES_BIT;
@ -1901,9 +1892,12 @@ BView::SetBlendingMode(source_alpha sourceAlpha, alpha_function alphaFunction)
if (fOwner) {
_CheckLockAndSwitchCurrent();
ViewBlendingModeInfo info;
info.sourceAlpha = sourceAlpha;
info.alphaFunction = alphaFunction;
fOwner->fLink->StartMessage(AS_VIEW_SET_BLENDING_MODE);
fOwner->fLink->Attach<int8>((int8)sourceAlpha);
fOwner->fLink->Attach<int8>((int8)alphaFunction);
fOwner->fLink->Attach<ViewBlendingModeInfo>(info);
fState->valid_flags |= B_VIEW_BLENDING_BIT;
}
@ -1926,12 +1920,11 @@ BView::GetBlendingMode(source_alpha *_sourceAlpha,
int32 code;
if (fOwner->fLink->FlushWithReply(code) == B_OK && code == B_OK) {
int8 alphaSourceMode, alphaFunctionMode;
fOwner->fLink->Read<int8>(&alphaSourceMode);
fOwner->fLink->Read<int8>(&alphaFunctionMode);
ViewBlendingModeInfo info;
fOwner->fLink->Read<ViewBlendingModeInfo>(&info);
fState->alpha_source_mode = (source_alpha)alphaSourceMode;
fState->alpha_function_mode = (alpha_function)alphaFunctionMode;
fState->alpha_source_mode = info.sourceAlpha;
fState->alpha_function_mode = info.alphaFunction;
fState->valid_flags |= B_VIEW_BLENDING_BIT;
}
@ -1963,8 +1956,7 @@ BView::MovePenTo(float x, float y)
_CheckLockAndSwitchCurrent();
fOwner->fLink->StartMessage(AS_VIEW_SET_PEN_LOC);
fOwner->fLink->Attach<float>(x);
fOwner->fLink->Attach<float>(y);
fOwner->fLink->Attach<BPoint>(BPoint(x, y));
fState->valid_flags |= B_VIEW_PEN_LOCATION_BIT;
}
@ -2387,11 +2379,14 @@ BView::DrawBitmapAsync(const BBitmap* bitmap, BRect bitmapRect, BRect viewRect,
_CheckLockAndSwitchCurrent();
ViewDrawBitmapInfo info;
info.bitmapToken = bitmap->_ServerToken();
info.options = options;
info.viewRect = viewRect;
info.bitmapRect = bitmapRect;
fOwner->fLink->StartMessage(AS_VIEW_DRAW_BITMAP);
fOwner->fLink->Attach<int32>(bitmap->_ServerToken());
fOwner->fLink->Attach<uint32>(options);
fOwner->fLink->Attach<BRect>(viewRect);
fOwner->fLink->Attach<BRect>(bitmapRect);
fOwner->fLink->Attach<ViewDrawBitmapInfo>(info);
_FlushIfNotInTransaction();
}
@ -2422,15 +2417,14 @@ BView::DrawBitmapAsync(const BBitmap* bitmap, BPoint where)
_CheckLockAndSwitchCurrent();
BRect bitmapRect = bitmap->Bounds().OffsetToCopy(B_ORIGIN);
BRect viewRect = bitmapRect.OffsetToCopy(where);
uint32 options = 0;
ViewDrawBitmapInfo info;
info.bitmapToken = bitmap->_ServerToken();
info.options = 0;
info.bitmapRect = bitmap->Bounds().OffsetToCopy(B_ORIGIN);
info.viewRect = info.bitmapRect.OffsetToCopy(where);
fOwner->fLink->StartMessage(AS_VIEW_DRAW_BITMAP);
fOwner->fLink->Attach<int32>(bitmap->_ServerToken());
fOwner->fLink->Attach<uint32>(options);
fOwner->fLink->Attach<BRect>(viewRect);
fOwner->fLink->Attach<BRect>(bitmapRect);
fOwner->fLink->Attach<ViewDrawBitmapInfo>(info);
_FlushIfNotInTransaction();
}
@ -2533,33 +2527,33 @@ BView::DrawString(const char *string, int32 length, escapement_delta *delta)
void
BView::DrawString(const char *string, int32 length, BPoint location,
escapement_delta *delta)
BView::DrawString(const char* string, int32 length, BPoint location,
escapement_delta* delta)
{
if (string == NULL || length < 1)
if (fOwner == NULL || string == NULL || length < 1)
return;
if (fOwner) {
_CheckLockAndSwitchCurrent();
_CheckLockAndSwitchCurrent();
// quite often delta will be NULL
if (delta)
fOwner->fLink->StartMessage(AS_DRAW_STRING_WITH_DELTA);
else
fOwner->fLink->StartMessage(AS_DRAW_STRING);
fOwner->fLink->Attach<int32>(length);
fOwner->fLink->Attach<BPoint>(location);
ViewDrawStringInfo info;
info.stringLength = length;
info.location = location;
if (delta != NULL)
info.delta = *delta;
if (delta)
fOwner->fLink->Attach<escapement_delta>(*delta);
// quite often delta will be NULL
if (delta)
fOwner->fLink->StartMessage(AS_DRAW_STRING_WITH_DELTA);
else
fOwner->fLink->StartMessage(AS_DRAW_STRING);
fOwner->fLink->AttachString(string, length);
fOwner->fLink->Attach<ViewDrawStringInfo>(info);
fOwner->fLink->Attach(string, length);
_FlushIfNotInTransaction();
_FlushIfNotInTransaction();
// this modifies our pen location, so we invalidate the flag.
fState->valid_flags &= ~B_VIEW_PEN_LOCATION_BIT;
}
// this modifies our pen location, so we invalidate the flag.
fState->valid_flags &= ~B_VIEW_PEN_LOCATION_BIT;
}
@ -3277,9 +3271,12 @@ BView::StrokeLine(BPoint pt0, BPoint pt1, ::pattern pattern)
_CheckLockAndSwitchCurrent();
_UpdatePattern(pattern);
ViewStrokeLineInfo info;
info.startPoint = pt0;
info.endPoint = pt1;
fOwner->fLink->StartMessage(AS_STROKE_LINE);
fOwner->fLink->Attach<BPoint>(pt0);
fOwner->fLink->Attach<BPoint>(pt1);
fOwner->fLink->Attach<ViewStrokeLineInfo>(info);
_FlushIfNotInTransaction();
@ -3386,7 +3383,7 @@ BView::BeginLineArray(int32 count)
fCommArray = new _array_data_;
fCommArray->maxCount = count;
fCommArray->count = 0;
fCommArray->array = new _array_hdr_[count];
fCommArray->array = new ViewLineArrayInfo[count];
}
@ -3403,10 +3400,8 @@ BView::AddLine(BPoint pt0, BPoint pt1, rgb_color col)
const uint32 &arrayCount = fCommArray->count;
if (arrayCount < fCommArray->maxCount) {
fCommArray->array[arrayCount].startX = pt0.x;
fCommArray->array[arrayCount].startY = pt0.y;
fCommArray->array[arrayCount].endX = pt1.x;
fCommArray->array[arrayCount].endY = pt1.y;
fCommArray->array[arrayCount].startPoint = pt0;
fCommArray->array[arrayCount].endPoint = pt1;
fCommArray->array[arrayCount].color = col;
fCommArray->count++;
@ -3420,7 +3415,7 @@ BView::EndLineArray()
if (fOwner == NULL)
return;
if (!fCommArray)
if (fCommArray == NULL)
debugger("Can't call EndLineArray before BeginLineArray");
_CheckLockAndSwitchCurrent();
@ -3428,7 +3423,7 @@ BView::EndLineArray()
fOwner->fLink->StartMessage(AS_STROKE_LINEARRAY);
fOwner->fLink->Attach<int32>(fCommArray->count);
fOwner->fLink->Attach(fCommArray->array,
fCommArray->count * sizeof(_array_hdr_));
fCommArray->count * sizeof(ViewLineArrayInfo));
_FlushIfNotInTransaction();

View File

@ -12,6 +12,7 @@
//! Data classes for working with BView states and draw parameters
#include "DrawState.h"
#include <new>
#include <stdio.h>
@ -20,8 +21,8 @@
#include "LinkReceiver.h"
#include "LinkSender.h"
#include "ServerProtocolStructs.h"
#include "DrawState.h"
using std::nothrow;
@ -183,24 +184,24 @@ DrawState::ReadFontFromLink(BPrivate::LinkReceiver& link)
void
DrawState::ReadFromLink(BPrivate::LinkReceiver& link)
{
rgb_color highColor;
rgb_color lowColor;
pattern patt;
ViewSetStateInfo info;
link.Read<BPoint>(&fPenLocation);
link.Read<float>(&fPenSize);
link.Read(&highColor, sizeof(rgb_color));
link.Read(&lowColor, sizeof(rgb_color));
link.Read(&patt, sizeof(pattern));
link.Read<int8>((int8*)&fDrawingMode);
link.Read<BPoint>(&fOrigin);
link.Read<int8>((int8*)&fLineJoinMode);
link.Read<int8>((int8*)&fLineCapMode);
link.Read<float>(&fMiterLimit);
link.Read<int8>((int8*)&fAlphaSrcMode);
link.Read<int8>((int8*)&fAlphaFncMode);
link.Read<float>(&fScale);
link.Read<bool>(&fFontAliasing);
link.Read<ViewSetStateInfo>(&info);
fPenLocation = info.penLocation;
fPenSize = info.penSize;
fHighColor = info.highColor;
fLowColor = info.lowColor;
fPattern = info.pattern;
fDrawingMode = info.drawingMode;
fOrigin = info.origin;
fScale = info.scale;
fLineJoinMode = info.lineJoin;
fLineCapMode = info.lineCap;
fMiterLimit = info.miterLimit;
fAlphaSrcMode = info.alphaSourceMode;
fAlphaFncMode = info.alphaFunctionMode;
fFontAliasing = info.fontAntialiasing;
if (fPreviousState) {
fCombinedOrigin = fPreviousState->fCombinedOrigin + fOrigin;
@ -210,11 +211,10 @@ DrawState::ReadFromLink(BPrivate::LinkReceiver& link)
fCombinedScale = fScale;
}
fHighColor = highColor;
fLowColor = lowColor;
fPattern = patt;
// read clipping
// TODO: This could be optimized, but the user clipping regions are rarely
// used, so it's low priority...
int32 clipRectCount;
link.Read<int32>(&clipRectCount);
@ -237,33 +237,39 @@ void
DrawState::WriteToLink(BPrivate::LinkSender& link) const
{
// Attach font state
link.Attach<uint32>(fFont.GetFamilyAndStyle());
link.Attach<float>(fFont.Size());
link.Attach<float>(fFont.Shear());
link.Attach<float>(fFont.Rotation());
link.Attach<float>(fFont.FalseBoldWidth());
link.Attach<uint8>(fFont.Spacing());
link.Attach<uint8>(fFont.Encoding());
link.Attach<uint16>(fFont.Face());
link.Attach<uint32>(fFont.Flags());
ViewGetStateInfo info;
info.fontID = fFont.GetFamilyAndStyle();
info.fontSize = fFont.Size();
info.fontShear = fFont.Shear();
info.fontRotation = fFont.Rotation();
info.fontFalseBoldWidth = fFont.FalseBoldWidth();
info.fontSpacing = fFont.Spacing();
info.fontEncoding = fFont.Encoding();
info.fontFace = fFont.Face();
info.fontFlags = fFont.Flags();
// Attach view state
link.Attach<BPoint>(fPenLocation);
link.Attach<float>(fPenSize);
link.Attach<rgb_color>(fHighColor);
link.Attach<rgb_color>(fLowColor);
link.Attach<uint64>(fPattern.GetInt64());
link.Attach<BPoint>(fOrigin);
link.Attach<uint8>((uint8)fDrawingMode);
link.Attach<uint8>((uint8)fLineCapMode);
link.Attach<uint8>((uint8)fLineJoinMode);
link.Attach<float>(fMiterLimit);
link.Attach<uint8>((uint8)fAlphaSrcMode);
link.Attach<uint8>((uint8)fAlphaFncMode);
link.Attach<float>(fScale);
link.Attach<bool>(fFontAliasing);
info.viewStateInfo.penLocation = fPenLocation;
info.viewStateInfo.penSize = fPenSize;
info.viewStateInfo.highColor = fHighColor;
info.viewStateInfo.lowColor = fLowColor;
info.viewStateInfo.pattern = (::pattern)fPattern.GetPattern();
info.viewStateInfo.drawingMode = fDrawingMode;
info.viewStateInfo.origin = fOrigin;
info.viewStateInfo.scale = fScale;
info.viewStateInfo.lineJoin = fLineJoinMode;
info.viewStateInfo.lineCap = fLineCapMode;
info.viewStateInfo.miterLimit = fMiterLimit;
info.viewStateInfo.alphaSourceMode = fAlphaSrcMode;
info.viewStateInfo.alphaFunctionMode = fAlphaFncMode;
info.viewStateInfo.fontAntialiasing = fFontAliasing;
link.Attach<ViewGetStateInfo>(info);
// TODO: Could be optimized, but is low prio, since most views do not
// use a custom clipping region...
if (fClippingRegion) {
int32 clippingRectCount = fClippingRegion->CountRects();
link.Attach<int32>(clippingRectCount);

View File

@ -43,6 +43,7 @@
#include <DirectWindowPrivate.h>
#include <MessagePrivate.h>
#include <PortLink.h>
#include <ServerProtocolStructs.h>
#include <ViewPrivate.h>
#include <WindowInfo.h>
#include <WindowPrivate.h>
@ -1545,17 +1546,15 @@ fDesktop->LockSingleWindow();
DTRACE(("ServerWindow %s: Message AS_VIEW_CURSOR: View: %s\n",
Title(), fCurrentView->Name()));
int32 token;
bool sync;
link.Read<int32>(&token);
if (link.Read<bool>(&sync) != B_OK)
ViewSetViewCursorInfo info;
if (link.Read<ViewSetViewCursorInfo>(&info) != B_OK)
break;
if (!fDesktop->GetCursorManager().Lock())
break;
ServerCursor* cursor
= fDesktop->GetCursorManager().FindCursor(token);
= fDesktop->GetCursorManager().FindCursor(info.cursorToken);
fCurrentView->SetCursor(cursor);
fDesktop->GetCursorManager().Unlock();
@ -1565,7 +1564,7 @@ fDesktop->LockSingleWindow();
if (fDesktop->ViewUnderMouse(fWindow) == fCurrentView->Token())
fServerApp->SetCurrentCursor(cursor);
}
if (sync) {
if (info.sync) {
// sync the client (it can now delete the cursor)
fLink.StartMessage(B_OK);
fLink.Flush();
@ -1612,21 +1611,16 @@ fDesktop->LockSingleWindow();
{
DTRACE(("ServerWindow %s: Message AS_VIEW_SET_LINE_MODE: "
"View: %s\n", Title(), fCurrentView->Name()));
int8 lineCap, lineJoin;
float miterLimit;
link.Read<int8>(&lineCap);
link.Read<int8>(&lineJoin);
if (link.Read<float>(&miterLimit) != B_OK)
ViewSetLineModeInfo info;
if (link.Read<ViewSetLineModeInfo>(&info) != B_OK)
break;
fCurrentView->CurrentState()->SetLineCapMode((cap_mode)lineCap);
fCurrentView->CurrentState()->SetLineJoinMode((join_mode)lineJoin);
fCurrentView->CurrentState()->SetMiterLimit(miterLimit);
fCurrentView->CurrentState()->SetLineCapMode(info.lineCap);
fCurrentView->CurrentState()->SetLineJoinMode(info.lineJoin);
fCurrentView->CurrentState()->SetMiterLimit(info.miterLimit);
fWindow->GetDrawingEngine()->SetStrokeMode((cap_mode)lineCap,
(join_mode)lineJoin, miterLimit);
// _UpdateDrawState(fCurrentView);
fWindow->GetDrawingEngine()->SetStrokeMode(info.lineCap,
info.lineJoin, info.miterLimit);
break;
}
@ -1634,10 +1628,13 @@ fDesktop->LockSingleWindow();
{
DTRACE(("ServerWindow %s: Message AS_VIEW_GET_LINE_MODE: "
"View: %s\n", Title(), fCurrentView->Name()));
ViewSetLineModeInfo info;
info.lineJoin = fCurrentView->CurrentState()->LineJoinMode();
info.lineCap = fCurrentView->CurrentState()->LineCapMode();
info.miterLimit = fCurrentView->CurrentState()->MiterLimit();
fLink.StartMessage(B_OK);
fLink.Attach<int8>((int8)(fCurrentView->CurrentState()->LineCapMode()));
fLink.Attach<int8>((int8)(fCurrentView->CurrentState()->LineJoinMode()));
fLink.Attach<float>(fCurrentView->CurrentState()->MiterLimit());
fLink.Attach<ViewSetLineModeInfo>(info);
fLink.Flush();
break;
@ -1690,16 +1687,15 @@ fDesktop->LockSingleWindow();
}
case AS_VIEW_SET_PEN_LOC:
{
float x, y;
link.Read<float>(&x);
if (link.Read<float>(&y) != B_OK)
BPoint location;
if (link.Read<BPoint>(&location) != B_OK)
break;
DTRACE(("ServerWindow %s: Message AS_VIEW_SET_PEN_LOC: "
"View: %s -> BPoint(%.1f, %.1f)\n", Title(),
fCurrentView->Name(), x, y));
fCurrentView->Name(), location.x, location.y));
fCurrentView->CurrentState()->SetPenLocation(BPoint(x, y));
fCurrentView->CurrentState()->SetPenLocation(location);
break;
}
case AS_VIEW_GET_PEN_LOC:
@ -1847,27 +1843,28 @@ fDesktop->LockSingleWindow();
{
DTRACE(("ServerWindow %s: Message AS_VIEW_SET_BLEND_MODE: "
"View: %s\n", Title(), fCurrentView->Name()));
int8 srcAlpha, alphaFunc;
link.Read<int8>(&srcAlpha);
if (link.Read<int8>(&alphaFunc) != B_OK)
ViewBlendingModeInfo info;
if (link.Read<ViewBlendingModeInfo>(&info) != B_OK)
break;
fCurrentView->CurrentState()->SetBlendingMode(
(source_alpha)srcAlpha, (alpha_function)alphaFunc);
info.sourceAlpha, info.alphaFunction);
fWindow->GetDrawingEngine()->SetBlendingMode(
(source_alpha)srcAlpha, (alpha_function)alphaFunc);
info.sourceAlpha, info.alphaFunction);
break;
}
case AS_VIEW_GET_BLENDING_MODE:
{
DTRACE(("ServerWindow %s: Message AS_VIEW_GET_BLEND_MODE: "
"View: %s\n", Title(), fCurrentView->Name()));
ViewBlendingModeInfo info;
info.sourceAlpha = fCurrentView->CurrentState()->AlphaSrcMode();
info.alphaFunction = fCurrentView->CurrentState()->AlphaFncMode();
fLink.StartMessage(B_OK);
fLink.Attach<int8>((int8)(
fCurrentView->CurrentState()->AlphaSrcMode()));
fLink.Attach<int8>((int8)(
fCurrentView->CurrentState()->AlphaFncMode()));
fLink.Attach<ViewBlendingModeInfo>(info);
fLink.Flush();
break;
@ -2286,27 +2283,23 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
switch (code) {
case AS_STROKE_LINE:
{
float x1, y1, x2, y2;
link.Read<float>(&x1);
link.Read<float>(&y1);
link.Read<float>(&x2);
if (link.Read<float>(&y2) != B_OK)
ViewStrokeLineInfo info;
if (link.Read<ViewStrokeLineInfo>(&info) != B_OK)
break;
DTRACE(("ServerWindow %s: Message AS_STROKE_LINE: View: %s -> "
"BPoint(%.1f, %.1f) - BPoint(%.1f, %.1f)\n", Title(),
fCurrentView->Name(), x1, y1, x2, y2));
fCurrentView->Name(),
info.startPoint.x, info.startPoint.y,
info.endPoint.x, info.endPoint.y));
BPoint p1(x1, y1);
BPoint p2(x2, y2);
BPoint penPos = p2;
fCurrentView->ConvertToScreenForDrawing(&p1);
fCurrentView->ConvertToScreenForDrawing(&p2);
drawingEngine->StrokeLine(p1, p2);
BPoint penPos = info.endPoint;
fCurrentView->ConvertToScreenForDrawing(&info.startPoint);
fCurrentView->ConvertToScreenForDrawing(&info.endPoint);
drawingEngine->StrokeLine(info.startPoint, info.endPoint);
// We update the pen here because many DrawingEngine calls which do not update the
// pen position actually call StrokeLine
// We update the pen here because many DrawingEngine calls which
// do not update the pen position actually call StrokeLine
// TODO: Decide where to put this, for example, it cannot be done
// for DrawString(), also there needs to be a decision, if penlocation
@ -2379,15 +2372,8 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
}
case AS_VIEW_DRAW_BITMAP:
{
int32 bitmapToken;
uint32 options;
BRect bitmapRect;
BRect viewRect;
link.Read<int32>(&bitmapToken);
link.Read<uint32>(&options);
link.Read<BRect>(&viewRect);
if (link.Read<BRect>(&bitmapRect) != B_OK)
ViewDrawBitmapInfo info;
if (link.Read<ViewDrawBitmapInfo>(&info) != B_OK)
break;
#if 0
@ -2395,23 +2381,24 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
options |= B_FILTER_BITMAP_BILINEAR;
#endif
ServerBitmap* bitmap = fServerApp->FindBitmap(bitmapToken);
ServerBitmap* bitmap = fServerApp->FindBitmap(info.bitmapToken);
if (bitmap) {
DTRACE(("ServerWindow %s: Message AS_VIEW_DRAW_BITMAP: "
"View: %s, bitmap: %ld (size %ld x %ld), "
"BRect(%.1f, %.1f, %.1f, %.1f) -> "
"BRect(%.1f, %.1f, %.1f, %.1f)\n",
fTitle, fCurrentView->Name(), bitmapToken,
fTitle, fCurrentView->Name(), info.bitmapToken,
bitmap->Width(), bitmap->Height(),
bitmapRect.left, bitmapRect.top, bitmapRect.right,
bitmapRect.bottom, viewRect.left, viewRect.top,
viewRect.right, viewRect.bottom));
info.bitmapRect.left, info.bitmapRect.top,
info.bitmapRect.right, info.bitmapRect.bottom,
info.viewRect.left, info.viewRect.top,
info.viewRect.right, info.viewRect.bottom));
fCurrentView->ConvertToScreenForDrawing(&viewRect);
fCurrentView->ConvertToScreenForDrawing(&info.viewRect);
drawingEngine->DrawBitmap(bitmap, bitmapRect, viewRect,
options);
drawingEngine->DrawBitmap(bitmap, info.bitmapRect,
info.viewRect, info.options);
}
break;
@ -2758,52 +2745,73 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
// 2) LineArrayData
int32 lineCount;
if (link.Read<int32>(&lineCount) != B_OK || lineCount <= 0)
break;
link.Read<int32>(&lineCount);
if (lineCount > 0) {
LineArrayData lineData[lineCount];
// To speed things up, try to use a stack allocation and only
// fall back to the heap if there are enough lines...
ViewLineArrayInfo* lineData;
static const int32 kStackBufferLineDataCount = 64;
ViewLineArrayInfo lineDataStackBuffer[kStackBufferLineDataCount];
if (lineCount > kStackBufferLineDataCount) {
lineData = new(std::nothrow) ViewLineArrayInfo[lineCount];
if (lineData == NULL)
break;
} else
lineData = lineDataStackBuffer;
for (int32 i = 0; i < lineCount; i++) {
LineArrayData* index = &lineData[i];
link.Read<float>(&(index->pt1.x));
link.Read<float>(&(index->pt1.y));
link.Read<float>(&(index->pt2.x));
link.Read<float>(&(index->pt2.y));
link.Read<rgb_color>(&(index->color));
fCurrentView->ConvertToScreenForDrawing(&index->pt1);
fCurrentView->ConvertToScreenForDrawing(&index->pt2);
}
drawingEngine->StrokeLineArray(lineCount, lineData);
// Read them all in one go
size_t dataSize = lineCount * sizeof(ViewLineArrayInfo);
if (link.Read(lineData, dataSize) != B_OK) {
if (lineData != lineDataStackBuffer)
delete[] lineData;
break;
}
// Convert to screen coords and draw
for (int32 i = 0; i < lineCount; i++) {
ViewLineArrayInfo* index = &lineData[i];
fCurrentView->ConvertToScreenForDrawing(&index->startPoint);
fCurrentView->ConvertToScreenForDrawing(&index->endPoint);
}
drawingEngine->StrokeLineArray(lineCount, lineData);
if (lineData != lineDataStackBuffer)
delete[] lineData;
break;
}
case AS_DRAW_STRING:
case AS_DRAW_STRING_WITH_DELTA:
{
char* string;
int32 length;
BPoint location;
escapement_delta _delta;
escapement_delta* delta = NULL;
link.Read<int32>(&length);
link.Read<BPoint>(&location);
if (code == AS_DRAW_STRING_WITH_DELTA) {
link.Read<escapement_delta>(&_delta);
if (_delta.nonspace != 0.0 || _delta.space != 0.0)
delta = &_delta;
}
if (link.ReadString(&string) != B_OK)
ViewDrawStringInfo info;
if (link.Read<ViewDrawStringInfo>(&info) != B_OK)
break;
char* string = (char*)malloc(info.stringLength + 1);
if (string == NULL)
break;
escapement_delta* delta = NULL;
if (code == AS_DRAW_STRING_WITH_DELTA) {
// In this case, info.delta will contain valid values.
delta = &info.delta;
}
if (link.Read(string, info.stringLength) != B_OK) {
free(string);
break;
}
// Terminate the string, if nothing else, it's important
// for the DTRACE call below...
string[info.stringLength] = '\0';
DTRACE(("ServerWindow %s: Message AS_DRAW_STRING, View: %s "
"-> %s\n", Title(), fCurrentView->Name(), string));
fCurrentView->ConvertToScreenForDrawing(&location);
BPoint penLocation = drawingEngine->DrawString(string, length,
location, delta);
fCurrentView->ConvertToScreenForDrawing(&info.location);
BPoint penLocation = drawingEngine->DrawString(string,
info.stringLength, info.location, delta);
fCurrentView->ConvertFromScreenForDrawing(&penLocation);
fCurrentView->CurrentState()->SetPenLocation(penLocation);
@ -2903,12 +2911,11 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link)
case AS_VIEW_SET_PEN_LOC:
{
float x, y;
link.Read<float>(&x);
link.Read<float>(&y);
picture->WriteSetPenLocation(BPoint(x, y));
BPoint location;
link.Read<BPoint>(&location);
picture->WriteSetPenLocation(location);
fCurrentView->CurrentState()->SetPenLocation(BPoint(x, y));
fCurrentView->CurrentState()->SetPenLocation(location);
break;
}
case AS_VIEW_SET_PEN_SIZE:
@ -2925,21 +2932,19 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link)
case AS_VIEW_SET_LINE_MODE:
{
int8 lineCap, lineJoin;
float miterLimit;
link.Read<int8>(&lineCap);
link.Read<int8>(&lineJoin);
link.Read<float>(&miterLimit);
ViewSetLineModeInfo info;
link.Read<ViewSetLineModeInfo>(&info);
picture->WriteSetLineMode((cap_mode)lineCap, (join_mode)lineJoin, miterLimit);
picture->WriteSetLineMode(info.lineCap, info.lineJoin,
info.miterLimit);
fCurrentView->CurrentState()->SetLineCapMode((cap_mode)lineCap);
fCurrentView->CurrentState()->SetLineJoinMode((join_mode)lineJoin);
fCurrentView->CurrentState()->SetMiterLimit(miterLimit);
fCurrentView->CurrentState()->SetLineCapMode(info.lineCap);
fCurrentView->CurrentState()->SetLineJoinMode(info.lineJoin);
fCurrentView->CurrentState()->SetMiterLimit(info.miterLimit);
fWindow->GetDrawingEngine()->SetStrokeMode((cap_mode)lineCap,
(join_mode)lineJoin, miterLimit);
fWindow->GetDrawingEngine()->SetStrokeMode(info.lineCap,
info.lineJoin, info.miterLimit);
break;
}
case AS_VIEW_SET_SCALE:
@ -3081,14 +3086,10 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link)
case AS_STROKE_LINE:
{
float x1, y1, x2, y2;
ViewStrokeLineInfo info;
link.Read<ViewStrokeLineInfo>(&info);
link.Read<float>(&x1);
link.Read<float>(&y1);
link.Read<float>(&x2);
link.Read<float>(&y2);
picture->WriteStrokeLine(BPoint(x1, y1), BPoint(x2, y2));
picture->WriteStrokeLine(info.startPoint, info.endPoint);
break;
}
@ -3102,17 +3103,13 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link)
picture->WritePushState();
for (int32 i = 0; i < lineCount; i++) {
float x1, y1, x2, y2;
link.Read<float>(&x1);
link.Read<float>(&y1);
link.Read<float>(&x2);
link.Read<float>(&y2);
ViewLineArrayInfo lineData;
if (link.Read<ViewLineArrayInfo >(&lineData) != B_OK)
break;
rgb_color color;
link.Read<rgb_color>(&color);
picture->WriteSetHighColor(color);
picture->WriteStrokeLine(BPoint(x1, y1), BPoint(x2, y2));
picture->WriteSetHighColor(lineData.color);
picture->WriteStrokeLine(lineData.startPoint,
lineData.endPoint);
}
picture->WritePopState();
@ -3139,18 +3136,29 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link)
case AS_DRAW_STRING:
case AS_DRAW_STRING_WITH_DELTA:
{
char* string = NULL;
int32 length;
BPoint location;
ViewDrawStringInfo info;
if (link.Read<ViewDrawStringInfo>(&info) != B_OK)
break;
link.Read<int32>(&length);
link.Read<BPoint>(&location);
escapement_delta delta = { 0, 0 };
if (code == AS_DRAW_STRING_WITH_DELTA)
link.Read<escapement_delta>(&delta);
link.ReadString(&string);
char* string = (char*)malloc(info.stringLength + 1);
if (string == NULL)
break;
picture->WriteDrawString(location, string, length, delta);
if (code != AS_DRAW_STRING_WITH_DELTA) {
// In this case, info.delta will NOT contain valid values.
info.delta = (escapement_delta){ 0, 0 };
}
if (link.Read(string, info.stringLength) != B_OK) {
free(string);
break;
}
// Terminate the string, if nothing else, it's important
// for the DTRACE call below...
string[info.stringLength] = '\0';
picture->WriteDrawString(info.location, string, info.stringLength,
info.delta);
free(string);
break;
@ -3190,25 +3198,17 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link)
case AS_VIEW_DRAW_BITMAP:
{
int32 token;
link.Read<int32>(&token);
ViewDrawBitmapInfo info;
link.Read<ViewDrawBitmapInfo>(&info);
uint32 options;
link.Read<uint32>(&options);
BRect viewRect;
link.Read<BRect>(&viewRect);
BRect bitmapRect;
link.Read<BRect>(&bitmapRect);
ServerBitmap *bitmap = App()->FindBitmap(token);
ServerBitmap *bitmap = App()->FindBitmap(info.bitmapToken);
if (bitmap == NULL)
break;
picture->WriteDrawBitmap(bitmapRect, viewRect, bitmap->Width(),
bitmap->Height(), bitmap->BytesPerRow(), bitmap->ColorSpace(),
options, bitmap->Bits(), bitmap->BitsLength());
picture->WriteDrawBitmap(info.bitmapRect, info.viewRect,
bitmap->Width(), bitmap->Height(), bitmap->BytesPerRow(),
bitmap->ColorSpace(), info.options, bitmap->Bits(),
bitmap->BitsLength());
break;
}
@ -3293,20 +3293,18 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link)
/*
case AS_VIEW_SET_BLENDING_MODE:
{
int8 srcAlpha, alphaFunc;
link.Read<int8>(&srcAlpha);
link.Read<int8>(&alphaFunc);
ViewBlendingModeInfo info;
link.Read<ViewBlendingModeInfo>(&info);
picture->BeginOp(B_PIC_SET_BLENDING_MODE);
picture->AddInt16((int16)srcAlpha);
picture->AddInt16((int16)alphaFunc);
picture->AddInt16((int16)info.sourceAlpha);
picture->AddInt16((int16)info.alphaFunction);
picture->EndOp();
fCurrentView->CurrentState()->SetBlendingMode((source_alpha)srcAlpha,
(alpha_function)alphaFunc);
fWindow->GetDrawingEngine()->SetBlendingMode((source_alpha)srcAlpha,
(alpha_function)alphaFunc);
fCurrentView->CurrentState()->SetBlendingMode(info.sourceAlpha,
info.alphaFunction);
fWindow->GetDrawingEngine()->SetBlendingMode(info.sourceAlpha,
info.alphaFunction);
break;
}*/
default:

View File

@ -1207,26 +1207,26 @@ DrawingEngine::StrokeLine(const BPoint &start, const BPoint &end)
// StrokeLineArray
void
DrawingEngine::StrokeLineArray(int32 numLines,
const LineArrayData *linedata)
const ViewLineArrayInfo *lineData)
{
CRASH_IF_NOT_LOCKED
if (!linedata || numLines <= 0)
if (!lineData || numLines <= 0)
return;
// figure out bounding box for line array
const LineArrayData *data = (const LineArrayData *)&(linedata[0]);
BRect touched(min_c(data->pt1.x, data->pt2.x),
min_c(data->pt1.y, data->pt2.y),
max_c(data->pt1.x, data->pt2.x),
max_c(data->pt1.y, data->pt2.y));
const ViewLineArrayInfo* data = (const ViewLineArrayInfo*)&(lineData[0]);
BRect touched(min_c(data->startPoint.x, data->endPoint.x),
min_c(data->startPoint.y, data->endPoint.y),
max_c(data->startPoint.x, data->endPoint.x),
max_c(data->startPoint.y, data->endPoint.y));
for (int32 i = 1; i < numLines; i++) {
data = (const LineArrayData *)&(linedata[i]);
BRect box(min_c(data->pt1.x, data->pt2.x),
min_c(data->pt1.y, data->pt2.y),
max_c(data->pt1.x, data->pt2.x),
max_c(data->pt1.y, data->pt2.y));
data = (const ViewLineArrayInfo*)&(lineData[i]);
BRect box(min_c(data->startPoint.x, data->endPoint.x),
min_c(data->startPoint.y, data->endPoint.y),
max_c(data->startPoint.x, data->endPoint.x),
max_c(data->startPoint.y, data->endPoint.y));
touched = touched | box;
}
extend_by_stroke_width(touched, fPainter->PenSize());
@ -1234,7 +1234,7 @@ DrawingEngine::StrokeLineArray(int32 numLines,
if (touched.IsValid()) {
AutoFloatingOverlaysHider _(fGraphicsCard, touched);
data = (const LineArrayData *)&(linedata[0]);
data = (const ViewLineArrayInfo*)&(lineData[0]);
// store current graphics state, we mess with the
// high color and pattern...
@ -1243,12 +1243,12 @@ DrawingEngine::StrokeLineArray(int32 numLines,
fPainter->SetHighColor(data->color);
fPainter->SetPattern(B_SOLID_HIGH);
fPainter->StrokeLine(data->pt1, data->pt2);
fPainter->StrokeLine(data->startPoint, data->endPoint);
for (int32 i = 1; i < numLines; i++) {
data = (const LineArrayData *)&(linedata[i]);
data = (const ViewLineArrayInfo*)&(lineData[i]);
fPainter->SetHighColor(data->color);
fPainter->StrokeLine(data->pt1, data->pt2);
fPainter->StrokeLine(data->startPoint, data->endPoint);
}
// restore correct drawing state highcolor and pattern

View File

@ -16,6 +16,7 @@
#include <Locker.h>
#include <Point.h>
#include <Gradient.h>
#include <ServerProtocolStructs.h>
#include "HWInterface.h"
@ -29,11 +30,6 @@ class ServerBitmap;
class ServerCursor;
class ServerFont;
typedef struct {
BPoint pt1;
BPoint pt2;
rgb_color color;
} LineArrayData;
class DrawingEngine : public HWInterfaceListener {
public:
@ -158,7 +154,7 @@ public:
const BPoint& end);
void StrokeLineArray(int32 numlines,
const LineArrayData* data);
const ViewLineArrayInfo* data);
// -------- text related calls

View File

@ -20,7 +20,7 @@ class BPoint;
class Pattern {
public:
Pattern(void) {}
Pattern() {}
Pattern(const uint64& p)
{ fPattern.type64 = p; }
@ -34,12 +34,15 @@ class Pattern {
Pattern(const pattern& src)
{ fPattern.type64 = *(uint64*)src.data; }
inline const int8* GetInt8(void) const
inline const int8* GetInt8() const
{ return fPattern.type8; }
inline uint64 GetInt64(void) const
inline uint64 GetInt64() const
{ return fPattern.type64; }
inline const ::pattern& GetPattern() const
{ return *(const ::pattern*)&fPattern.type64; }
inline void Set(const int8* p)
{ fPattern.type64 = *((const uint64*)p); }