app_server: Make use of BReferenceable in AlphaMask.

Extracted from https://review.haiku-os.org/c/haiku/+/2695
with a few minor tweaks.

May help with #16246, but I could only reproduce it intermittently.
This commit is contained in:
Augustin Cavalier 2020-06-20 20:02:35 -04:00
parent 67ace0bfab
commit 176d0e1041
2 changed files with 18 additions and 30 deletions

View File

@ -75,7 +75,6 @@ AlphaMask::AlphaMask(AlphaMask* previousMask, AlphaMask* other)
if (previousMask != NULL)
atomic_add(&previousMask->fNextMaskCount, 1);
fBits->AcquireReference();
}
@ -102,8 +101,6 @@ AlphaMask::AlphaMask(uint8 backgroundOpacity)
AlphaMask::~AlphaMask()
{
if (fBits != NULL)
fBits->ReleaseReference();
if (fPreviousMask.Get() != NULL)
atomic_add(&fPreviousMask->fNextMaskCount, -1);
@ -153,19 +150,17 @@ AlphaMask::BitmapSize() const
ServerBitmap*
AlphaMask::_CreateTemporaryBitmap(BRect bounds) const
{
UtilityBitmap* bitmap = new(std::nothrow) UtilityBitmap(bounds,
B_RGBA32, 0);
BReference<UtilityBitmap> bitmap(new(std::nothrow) UtilityBitmap(bounds,
B_RGBA32, 0), true);
if (bitmap == NULL)
return NULL;
if (!bitmap->IsValid()) {
delete bitmap;
if (!bitmap->IsValid())
return NULL;
}
memset(bitmap->Bits(), fBackgroundOpacity, bitmap->BitsLength());
return bitmap;
return bitmap.Detach();
}
@ -184,9 +179,7 @@ AlphaMask::_Generate()
return;
}
if (fBits != NULL)
fBits->ReleaseReference();
fBits = new(std::nothrow) UtilityBitmap(fBounds, B_GRAY8, 0);
fBits.SetTo(new(std::nothrow) UtilityBitmap(fBounds, B_GRAY8, 0), true);
if (fBits == NULL)
return;
@ -339,17 +332,16 @@ VectorAlphaMask<VectorMaskType>::_RenderSource(const IntRect& canvasBounds)
if (!fBounds.IsValid())
return NULL;
ServerBitmap* bitmap = _CreateTemporaryBitmap(fBounds);
BReference<ServerBitmap> bitmap(_CreateTemporaryBitmap(fBounds), true);
if (bitmap == NULL)
return NULL;
// Render the picture to the bitmap
BitmapHWInterface interface(bitmap);
DrawingEngine* engine = interface.CreateDrawingEngine();
if (engine == NULL) {
bitmap->ReleaseReference();
if (engine == NULL)
return NULL;
}
engine->SetRendererOffset(fBounds.left, fBounds.top);
OffscreenCanvas canvas(engine,
@ -374,7 +366,7 @@ VectorAlphaMask<VectorMaskType>::_RenderSource(const IntRect& canvasBounds)
canvas.PopState();
delete engine;
return bitmap;
return bitmap.Detach();
}
@ -458,7 +450,7 @@ ShapeAlphaMask::ShapeAlphaMask(AlphaMask* previousMask,
const shape_data& shape, BPoint where, bool inverse)
:
VectorAlphaMask<ShapeAlphaMask>(previousMask, where, inverse),
fShape(new(std::nothrow) shape_data(shape))
fShape(new(std::nothrow) shape_data(shape), true)
{
if (fDrawState == NULL)
fDrawState = new(std::nothrow) DrawState();
@ -474,13 +466,11 @@ ShapeAlphaMask::ShapeAlphaMask(AlphaMask* previousMask,
fShape(other->fShape),
fShapeBounds(other->fShapeBounds)
{
fShape->AcquireReference();
}
ShapeAlphaMask::~ShapeAlphaMask()
{
fShape->ReleaseReference();
}
@ -489,25 +479,23 @@ ShapeAlphaMask::Create(AlphaMask* previousMask, const shape_data& shape,
BPoint where, bool inverse)
{
// Look if we have a suitable cached mask
ShapeAlphaMask* mask = AlphaMaskCache::Default()->Get(shape, previousMask,
inverse);
BReference<ShapeAlphaMask> mask(AlphaMaskCache::Default()->Get(shape,
previousMask, inverse), true);
if (mask == NULL) {
// No cached mask, create new one
mask = new(std::nothrow) ShapeAlphaMask(previousMask, shape,
BPoint(0, 0), inverse);
mask.SetTo(new(std::nothrow) ShapeAlphaMask(previousMask, shape,
BPoint(0, 0), inverse), true);
} else {
// Create new mask which reuses the parameters and the mask bitmap
// of the cache entry
// TODO: don't make a new mask if the cache entry has no drawstate
// using it anymore, because then we ca just immediately reuse it
AlphaMask* cachedMask = mask;
RecursiveLocker locker(mask->fLock);
mask = new(std::nothrow) ShapeAlphaMask(previousMask, mask);
cachedMask->ReleaseReference();
mask.SetTo(new(std::nothrow) ShapeAlphaMask(previousMask, mask), true);
}
return mask;
return mask.Detach();
}

View File

@ -82,7 +82,7 @@ private:
// one in the cache, without being
// in the cache itself
UtilityBitmap* fBits;
BReference<UtilityBitmap> fBits;
agg::rendering_buffer fBuffer;
agg::clipped_alpha_mask fMask;
scanline_unpacked_masked_type fScanline;
@ -172,7 +172,7 @@ private:
private:
friend class AlphaMaskCache;
shape_data* fShape;
BReference<shape_data> fShape;
BRect fShapeBounds;
static DrawState* fDrawState;
};