app_server: Move AlphaMask management into DrawState.

* Give DrawState a real copy constructor, handle deriving in PushState().
   (Although clipping region and alpha mask are not cloned, which is on the
   other hand just what's needed for now.)
 * Combining alpha masks from previous states is not yet handled.
 * Remove SetAlphaMask() from DrawingEngine and Painter. It is now done in
   SetDrawState().
This commit is contained in:
Stephan Aßmus
2014-01-28 23:27:12 +01:00
parent a2f075eb42
commit 215119a1e7
12 changed files with 136 additions and 116 deletions
+4 -1
View File
@@ -12,6 +12,7 @@
#include "BitmapHWInterface.h"
#include "BitmapManager.h"
#include "DrawingEngine.h"
#include "DrawState.h"
#include "ServerBitmap.h"
#include "View.h"
@@ -101,7 +102,9 @@ AlphaMask::_RenderPicture(ServerPicture* picture, bool inverse) const
// Copy the current state of the client view, so we draw with the right
// font, color and everything
engine->SetDrawState(fView->CurrentState());
DrawState drawState(*fView->CurrentState());
engine->SetDrawState(&drawState);
OffscreenContext context(engine);
if (engine->LockParallelAccess()) {
// FIXME ConstrainClippingRegion docs says passing NULL disables
+81 -45
View File
@@ -19,6 +19,7 @@
#include <Region.h>
#include "AlphaMask.h"
#include "LinkReceiver.h"
#include "LinkSender.h"
#include "ServerProtocolStructs.h"
@@ -28,66 +29,70 @@ using std::nothrow;
DrawState::DrawState()
: fOrigin(0.0, 0.0),
fCombinedOrigin(0.0, 0.0),
fScale(1.0),
fCombinedScale(1.0),
fClippingRegion(NULL),
:
fOrigin(0.0, 0.0),
fCombinedOrigin(0.0, 0.0),
fScale(1.0),
fCombinedScale(1.0),
fClippingRegion(NULL),
fAlphaMask(NULL),
fHighColor((rgb_color){ 0, 0, 0, 255 }),
fLowColor((rgb_color){ 255, 255, 255, 255 }),
fPattern(kSolidHigh),
fHighColor((rgb_color){ 0, 0, 0, 255 }),
fLowColor((rgb_color){ 255, 255, 255, 255 }),
fPattern(kSolidHigh),
fDrawingMode(B_OP_COPY),
fAlphaSrcMode(B_PIXEL_ALPHA),
fAlphaFncMode(B_ALPHA_OVERLAY),
fDrawingMode(B_OP_COPY),
fAlphaSrcMode(B_PIXEL_ALPHA),
fAlphaFncMode(B_ALPHA_OVERLAY),
fPenLocation(0.0, 0.0),
fPenSize(1.0),
fPenLocation(0.0, 0.0),
fPenSize(1.0),
fFontAliasing(false),
fSubPixelPrecise(false),
fLineCapMode(B_BUTT_CAP),
fLineJoinMode(B_MITER_JOIN),
fMiterLimit(B_DEFAULT_MITER_LIMIT),
fPreviousState(NULL)
fFontAliasing(false),
fSubPixelPrecise(false),
fLineCapMode(B_BUTT_CAP),
fLineJoinMode(B_MITER_JOIN),
fMiterLimit(B_DEFAULT_MITER_LIMIT),
fPreviousState(NULL)
{
fUnscaledFontSize = fFont.Size();
}
DrawState::DrawState(DrawState* from)
: fOrigin(0.0, 0.0),
fCombinedOrigin(from->fCombinedOrigin),
fScale(1.0),
fCombinedScale(from->fCombinedScale),
fClippingRegion(NULL),
DrawState::DrawState(const DrawState& other)
:
fOrigin(other.fOrigin),
fCombinedOrigin(other.fCombinedOrigin),
fScale(other.fScale),
fCombinedScale(other.fCombinedScale),
fClippingRegion(NULL),
fAlphaMask(NULL),
fHighColor(from->fHighColor),
fLowColor(from->fLowColor),
fPattern(from->fPattern),
fHighColor(other.fHighColor),
fLowColor(other.fLowColor),
fPattern(other.fPattern),
fDrawingMode(from->fDrawingMode),
fAlphaSrcMode(from->fAlphaSrcMode),
fAlphaFncMode(from->fAlphaFncMode),
fDrawingMode(other.fDrawingMode),
fAlphaSrcMode(other.fAlphaSrcMode),
fAlphaFncMode(other.fAlphaFncMode),
fPenLocation(from->fPenLocation),
fPenSize(from->fPenSize),
fPenLocation(other.fPenLocation),
fPenSize(other.fPenSize),
fFont(from->fFont),
fFontAliasing(from->fFontAliasing),
fFont(other.fFont),
fFontAliasing(other.fFontAliasing),
fSubPixelPrecise(from->fSubPixelPrecise),
fSubPixelPrecise(other.fSubPixelPrecise),
fLineCapMode(from->fLineCapMode),
fLineJoinMode(from->fLineJoinMode),
fMiterLimit(from->fMiterLimit),
fLineCapMode(other.fLineCapMode),
fLineJoinMode(other.fLineJoinMode),
fMiterLimit(other.fMiterLimit),
// Since fScale is reset to 1.0, the unscaled
// font size is the current size of the font
// (which is from->fUnscaledFontSize * from->fCombinedScale)
fUnscaledFontSize(from->fUnscaledFontSize),
fPreviousState(from)
// Since fScale is reset to 1.0, the unscaled
// font size is the current size of the font
// (which is from->fUnscaledFontSize * from->fCombinedScale)
fUnscaledFontSize(other.fUnscaledFontSize),
fPreviousState(NULL)
{
}
@@ -96,13 +101,22 @@ DrawState::~DrawState()
{
delete fClippingRegion;
delete fPreviousState;
delete fAlphaMask;
}
DrawState*
DrawState::PushState()
{
DrawState* next = new (nothrow) DrawState(this);
DrawState* next = new (nothrow) DrawState(*this);
if (next != NULL) {
// Prepare state as derived from this state
next->fOrigin = BPoint(0.0, 0.0);
next->fScale = 1.0;
next->fPreviousState = this;
}
return next;
}
@@ -373,6 +387,28 @@ DrawState::GetCombinedClippingRegion(BRegion* region) const
}
void
DrawState::SetAlphaMask(AlphaMask* mask)
{
// BeOS compatibility: they implemented ClipToPicture by converting the
// picture to a complex BRegion and used that as a clipping region. As a
// result, youcan't have a picture and a region clipping at the same level
// (but you can either using PushState/PopState, or using
// ConstrainClippingRegion after ClipToPicture...)
// SetClippingRegion(NULL);
delete fAlphaMask;
fAlphaMask = mask;
}
AlphaMask*
DrawState::GetAlphaMask() const
{
return fAlphaMask;
}
// #pragma mark -
+7 -2
View File
@@ -20,6 +20,7 @@
#include "ServerFont.h"
#include "PatternHandler.h"
class AlphaMask;
class BRegion;
namespace BPrivate {
@@ -31,8 +32,7 @@ namespace BPrivate {
class DrawState {
public:
DrawState();
private:
DrawState(DrawState* from);
DrawState(const DrawState& other);
public:
virtual ~DrawState();
@@ -67,6 +67,9 @@ public:
bool HasAdditionalClipping() const;
bool GetCombinedClippingRegion(BRegion* region) const;
void SetAlphaMask(AlphaMask* mask);
AlphaMask* GetAlphaMask() const;
// coordinate transformations
void Transform(float* x, float* y) const;
void InverseTransform(float* x, float* y) const;
@@ -149,6 +152,8 @@ protected:
BRegion* fClippingRegion;
AlphaMask* fAlphaMask;
rgb_color fHighColor;
rgb_color fLowColor;
Pattern fPattern;
+21 -3
View File
@@ -31,7 +31,11 @@ DrawingContext::DrawingContext()
fDrawState(new (std::nothrow) DrawState)
{
}
DrawingContext::~DrawingContext()
{
}
status_t
@@ -108,7 +112,7 @@ DrawingContext::SetScale(float scale)
float
DrawingContext::Scale() const
{
return CurrentState()->Scale();
return fDrawState->Scale();
}
@@ -117,11 +121,25 @@ DrawingContext::SetUserClipping(const BRegion* region)
{
fDrawState->SetClippingRegion(region);
// rebuild clipping (for just this view)
// rebuild clipping (for just this context)
RebuildClipping(false);
}
void
DrawingContext::SetAlphaMask(AlphaMask* mask)
{
fDrawState->SetAlphaMask(mask);
}
AlphaMask*
DrawingContext::GetAlphaMask() const
{
return fDrawState->GetAlphaMask();
}
//! converts a point from local *drawing* to screen coordinate system
void
DrawingContext::ConvertToScreenForDrawing(BPoint* point) const
+11 -5
View File
@@ -17,6 +17,7 @@
#include <Point.h>
class AlphaMask;
class BGradient;
class BRegion;
class DrawingEngine;
@@ -27,8 +28,10 @@ class ServerPicture;
class DrawingContext {
public:
public:
DrawingContext();
virtual ~DrawingContext();
status_t InitCheck() const;
virtual void PushState();
@@ -43,7 +46,10 @@ class DrawingContext {
void SetUserClipping(const BRegion* region);
// region is expected in view coordinates
void SetAlphaMask(AlphaMask* mask);
AlphaMask* GetAlphaMask() const;
void ConvertToScreenForDrawing(BPoint* point) const;
void ConvertToScreenForDrawing(BRect* rect) const;
void ConvertToScreenForDrawing(BRegion* region) const;
@@ -70,13 +76,13 @@ class DrawingContext {
virtual void ResyncDrawState() {};
virtual void UpdateCurrentDrawingRegion() {};
protected:
protected:
DrawState* fDrawState;
};
class OffscreenContext: public DrawingContext {
public:
public:
OffscreenContext(DrawingEngine* engine)
: fDrawingEngine(engine)
{};
@@ -96,7 +102,7 @@ class OffscreenContext: public DrawingContext {
void RebuildClipping(bool deep) { /* TODO */ }
ServerPicture* GetPicture(int32 token) const
{ /* TODO */ return NULL; }
private:
private:
DrawingEngine* fDrawingEngine;
};
+7 -4
View File
@@ -51,6 +51,7 @@
#include "clipping.h"
#include "utf8_functions.h"
#include "AlphaMask.h"
#include "AppServer.h"
#include "AutoDeleter.h"
#include "BBitmapBuffer.h"
@@ -1869,7 +1870,8 @@ fDesktop->LockSingleWindow();
link.Read<int32>(&pictureToken);
if (pictureToken < 0) {
fCurrentView->SetAlphaMask(NULL, false, B_ORIGIN);
fCurrentView->SetAlphaMask(NULL);
_UpdateDrawState(fCurrentView);
break;
}
@@ -1881,7 +1883,10 @@ fDesktop->LockSingleWindow();
if (picture == NULL)
break;
fCurrentView->SetAlphaMask(picture, inverse, where);
fCurrentView->SetAlphaMask(new(std::nothrow) AlphaMask(
fCurrentView, picture, inverse, where));
_UpdateDrawState(fCurrentView);
picture->ReleaseReference();
break;
}
@@ -2174,7 +2179,6 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
// that's why you need to use the clipping only for as long
// as you have it locked
drawingEngine->ConstrainClippingRegion(&fCurrentDrawingRegion);
drawingEngine->SetAlphaMask(fCurrentView->GetAlphaMask());
switch (code) {
case AS_STROKE_LINE:
@@ -2840,7 +2844,6 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
break;
}
drawingEngine->SetAlphaMask(NULL);
drawingEngine->UnlockParallelAccess();
}
-28
View File
@@ -113,7 +113,6 @@ View::View(IntRect frame, IntPoint scrollingOffset, const char* name,
fCursor(NULL),
fPicture(NULL),
fAlphaMask(NULL),
fLocalClipping((BRect)Bounds()),
fScreenClipping(),
@@ -134,7 +133,6 @@ View::~View()
delete fScreenAndUserClipping;
delete fUserClipping;
delete fDrawState;
delete fAlphaMask;
// if (fWindow && this == fWindow->TopView())
// fWindow->SetTopView(NULL);
@@ -1575,32 +1573,6 @@ View::InvalidateScreenClipping()
}
// TODO we should be storing the ServerPicture here, so we can recompute the
// bitmap mask when the view is scaled, resized or the origin is changed.
// This would allow us to keep a bitmap mask matching exactly the view size.
// Moreover, we should clip that bitmap mask using the region-based clipping,
// so it can mask out all the clipped regions, and we don't have to worry about
// them whendoing further drawing. Essentially, switch from region-based to
// bitmap based clipping for all ourdrawing.
void
View::SetAlphaMask(ServerPicture* picture, bool inverse, BPoint origin)
{
// BeOS compatibility: they implemented ClipToPicture by converting the
// picture to a complex BRegion and used that as a clipping region. As a
// result, youcan't have a picture and a region clipping at the same level
// (but you can either using PushState/PopState, or using
// ConstrainClippingRegion after ClipToPicture...)
// SetUserClipping(NULL);
delete fAlphaMask;
if (picture != NULL) {
fAlphaMask = new(std::nothrow) AlphaMask(this, picture, inverse,
origin);
} else
fAlphaMask = NULL;
}
BRegion&
View::_ScreenClipping(BRegion* windowContentClipping, bool force) const
{
-6
View File
@@ -29,7 +29,6 @@ namespace BPrivate {
class PortLink;
};
class AlphaMask;
class DrawingEngine;
class Overlay;
class Window;
@@ -221,10 +220,6 @@ public:
&& fScreenAndUserClipping != NULL));
}
void SetAlphaMask(ServerPicture* picture, bool inverse,
BPoint where);
AlphaMask* GetAlphaMask() { return fAlphaMask; }
// debugging
void PrintToStream() const;
#if 0
@@ -274,7 +269,6 @@ protected:
ServerCursor* fCursor;
ServerPicture* fPicture;
AlphaMask* fAlphaMask;
// clipping
BRegion fLocalClipping;
-11
View File
@@ -17,7 +17,6 @@
#include <algorithm>
#include <stack>
#include "AlphaMask.h"
#include "DrawState.h"
#include "GlyphLayoutEngine.h"
#include "Painter.h"
@@ -235,16 +234,6 @@ DrawingEngine::ConstrainClippingRegion(const BRegion* region)
}
void
DrawingEngine::SetAlphaMask(AlphaMask* mask)
{
scanline_unpacked_masked_type* scanline = NULL;
if (mask != NULL)
scanline = mask->Generate();
fPainter->SetAlphaMask(scanline);
}
void
DrawingEngine::SetDrawState(const DrawState* state, int32 xOffset,
int32 yOffset)
-2
View File
@@ -25,7 +25,6 @@ class BPoint;
class BRect;
class BRegion;
class AlphaMask;
class DrawState;
class Painter;
class ServerBitmap;
@@ -68,7 +67,6 @@ public:
// clipping for all drawing functions, passing a NULL region
// will remove any clipping (drawing allowed everywhere)
virtual void ConstrainClippingRegion(const BRegion* region);
void SetAlphaMask(AlphaMask* mask);
virtual void SetDrawState(const DrawState* state,
int32 xOffset = 0, int32 yOffset = 0);
+5 -7
View File
@@ -289,6 +289,11 @@ Painter::SetDrawState(const DrawState* data, int32 xOffset, int32 yOffset)
fSubpixelPrecise = data->SubPixelPrecise();
if (data->GetAlphaMask() != NULL)
fMaskedUnpackedScanline = data->GetAlphaMask()->Generate();
else
fMaskedUnpackedScanline = NULL;
// any of these conditions means we need to use a different drawing
// mode instance
bool updateDrawingMode
@@ -336,13 +341,6 @@ Painter::ConstrainClipping(const BRegion* region)
}
void
Painter::SetAlphaMask(scanline_unpacked_masked_type* mask)
{
fMaskedUnpackedScanline = mask;
}
// SetHighColor
void
Painter::SetHighColor(const rgb_color& color)
@@ -54,8 +54,6 @@ public:
void ConstrainClipping(const BRegion* region);
const BRegion* ClippingRegion() const
{ return fClippingRegion; }
void SetAlphaMask(
scanline_unpacked_masked_type* mask);
void SetDrawState(const DrawState* data,
int32 xOffset = 0,