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