app_server: add support for uniform opacity alpha masks

* Another constructor for AlphaMask allows creating a mask with no
  picture, it will simply be a single uniform alpha value over the
  whole mask.

* No need to even allocate a buffer in this case, we can just use
  the feature of clipped_alpha_mask to define an opacity for outside
  the mask, and set the buffer size to zero.
This commit is contained in:
Julian Harnath
2015-07-25 16:31:20 +02:00
parent edc0b5e9db
commit 6ac468ef24
2 changed files with 59 additions and 8 deletions
+48 -7
View File
@@ -1,10 +1,11 @@
/*
* Copyright 2014, Haiku, Inc.
* Copyright 2014-2015, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Authors:
* Adrien Destugues <[email protected]>
* Stephan Aßmus <[email protected]>
* Julian Harnath <[email protected]>
*/
@@ -26,6 +27,7 @@ AlphaMask::AlphaMask(ServerPicture* picture, bool inverse, BPoint origin,
fPicture(picture),
fInverse(inverse),
fOrigin(origin),
fBackgroundOpacity(0),
fDrawState(drawState),
fViewBounds(),
@@ -43,9 +45,34 @@ AlphaMask::AlphaMask(ServerPicture* picture, bool inverse, BPoint origin,
}
AlphaMask::AlphaMask(uint8 backgroundOpacity)
:
fPreviousMask(NULL),
fPicture(NULL),
fInverse(false),
fOrigin(0, 0),
fBackgroundOpacity(backgroundOpacity),
fDrawState(),
fViewBounds(),
fViewOffset(),
fCachedBitmap(NULL),
fCachedBounds(),
fCachedOffset(),
fBuffer(),
fCachedMask(),
fScanline(fCachedMask)
{
}
AlphaMask::~AlphaMask()
{
fPicture->ReleaseReference();
if (fPicture != NULL)
fPicture->ReleaseReference();
delete[] fCachedBitmap;
SetPrevious(NULL);
}
@@ -81,7 +108,13 @@ AlphaMask::SetPrevious(AlphaMask* mask)
scanline_unpacked_masked_type*
AlphaMask::Generate()
{
if (fPicture == NULL || !fViewBounds.IsValid())
if (fPicture == NULL) {
fBuffer.attach(NULL, 0, 0, 0);
_AttachMaskToBuffer();
return &fScanline;
}
if (!fViewBounds.IsValid())
return NULL;
// See if a cached bitmap can be used. Don't use it when the view offset
@@ -162,9 +195,7 @@ AlphaMask::Generate()
fCachedOffset = fViewOffset;
fBuffer.attach(fCachedBitmap, width, height, width);
fCachedMask.attach(fBuffer, fViewOffset.x + fOrigin.x,
fViewOffset.y + fOrigin.y, fInverse ? 255 : 0);
_AttachMaskToBuffer();
return &fScanline;
}
@@ -184,7 +215,7 @@ AlphaMask::_RenderPicture() const
}
// Clear the bitmap with the transparent color
memset(bitmap->Bits(), 0, bitmap->BitsLength());
memset(bitmap->Bits(), fBackgroundOpacity, bitmap->BitsLength());
// Render the picture to the bitmap
BitmapHWInterface interface(bitmap);
@@ -213,3 +244,13 @@ AlphaMask::_RenderPicture() const
return bitmap;
}
void
AlphaMask::_AttachMaskToBuffer()
{
uint8 outsideOpacity = fInverse ? 255 - fBackgroundOpacity
: fBackgroundOpacity;
fCachedMask.attach(fBuffer, fViewOffset.x + fOrigin.x,
fViewOffset.y + fOrigin.y, outsideOpacity);
}
+11 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2014, Haiku, Inc.
* Copyright 2014-2015, Haiku, Inc.
* Distributed under the terms of the MIT License.
*/
@@ -23,6 +23,7 @@ class AlphaMask : public BReferenceable {
public:
AlphaMask(ServerPicture* mask, bool inverse,
BPoint origin, const DrawState& drawState);
AlphaMask(uint8 backgroundOpacity);
~AlphaMask();
void Update(BRect bounds, BPoint offset);
@@ -33,6 +34,7 @@ public:
private:
ServerBitmap* _RenderPicture() const;
void _AttachMaskToBuffer();
private:
@@ -41,10 +43,18 @@ private:
ServerPicture* fPicture;
const bool fInverse;
BPoint fOrigin;
// position of this mask, relative to
// either its parent mask, or (if there
// is none) the canvas
uint8 fBackgroundOpacity;
DrawState fDrawState;
// draw state used for drawing fPicture
BRect fViewBounds;
// determines alpha mask size
BPoint fViewOffset;
// position of alpha mask in screen
// coordinates
uint8* fCachedBitmap;
BRect fCachedBounds;