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. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Adrien Destugues <[email protected]> * Adrien Destugues <[email protected]>
* Stephan Aßmus <[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), fPicture(picture),
fInverse(inverse), fInverse(inverse),
fOrigin(origin), fOrigin(origin),
fBackgroundOpacity(0),
fDrawState(drawState), fDrawState(drawState),
fViewBounds(), 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() AlphaMask::~AlphaMask()
{ {
fPicture->ReleaseReference(); if (fPicture != NULL)
fPicture->ReleaseReference();
delete[] fCachedBitmap; delete[] fCachedBitmap;
SetPrevious(NULL); SetPrevious(NULL);
} }
@@ -81,7 +108,13 @@ AlphaMask::SetPrevious(AlphaMask* mask)
scanline_unpacked_masked_type* scanline_unpacked_masked_type*
AlphaMask::Generate() AlphaMask::Generate()
{ {
if (fPicture == NULL || !fViewBounds.IsValid()) if (fPicture == NULL) {
fBuffer.attach(NULL, 0, 0, 0);
_AttachMaskToBuffer();
return &fScanline;
}
if (!fViewBounds.IsValid())
return NULL; return NULL;
// See if a cached bitmap can be used. Don't use it when the view offset // See if a cached bitmap can be used. Don't use it when the view offset
@@ -162,9 +195,7 @@ AlphaMask::Generate()
fCachedOffset = fViewOffset; fCachedOffset = fViewOffset;
fBuffer.attach(fCachedBitmap, width, height, width); fBuffer.attach(fCachedBitmap, width, height, width);
_AttachMaskToBuffer();
fCachedMask.attach(fBuffer, fViewOffset.x + fOrigin.x,
fViewOffset.y + fOrigin.y, fInverse ? 255 : 0);
return &fScanline; return &fScanline;
} }
@@ -184,7 +215,7 @@ AlphaMask::_RenderPicture() const
} }
// Clear the bitmap with the transparent color // 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 // Render the picture to the bitmap
BitmapHWInterface interface(bitmap); BitmapHWInterface interface(bitmap);
@@ -213,3 +244,13 @@ AlphaMask::_RenderPicture() const
return bitmap; 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. * Distributed under the terms of the MIT License.
*/ */
@@ -23,6 +23,7 @@ class AlphaMask : public BReferenceable {
public: public:
AlphaMask(ServerPicture* mask, bool inverse, AlphaMask(ServerPicture* mask, bool inverse,
BPoint origin, const DrawState& drawState); BPoint origin, const DrawState& drawState);
AlphaMask(uint8 backgroundOpacity);
~AlphaMask(); ~AlphaMask();
void Update(BRect bounds, BPoint offset); void Update(BRect bounds, BPoint offset);
@@ -33,6 +34,7 @@ public:
private: private:
ServerBitmap* _RenderPicture() const; ServerBitmap* _RenderPicture() const;
void _AttachMaskToBuffer();
private: private:
@@ -41,10 +43,18 @@ private:
ServerPicture* fPicture; ServerPicture* fPicture;
const bool fInverse; const bool fInverse;
BPoint fOrigin; BPoint fOrigin;
// position of this mask, relative to
// either its parent mask, or (if there
// is none) the canvas
uint8 fBackgroundOpacity;
DrawState fDrawState; DrawState fDrawState;
// draw state used for drawing fPicture
BRect fViewBounds; BRect fViewBounds;
// determines alpha mask size
BPoint fViewOffset; BPoint fViewOffset;
// position of alpha mask in screen
// coordinates
uint8* fCachedBitmap; uint8* fCachedBitmap;
BRect fCachedBounds; BRect fCachedBounds;