From 4acb99b60f38da581d1409e9ffd3c4ab8fe95041 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Thu, 29 Dec 2005 15:36:18 +0000 Subject: [PATCH] Implemented reference counting of ServerBitmaps, made constructor and destructor private, as only the BitmapManager class is allowed to call them. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15718 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/servers/app/ServerBitmap.h | 85 +++++++++------------- src/servers/app/BitmapManager.cpp | 6 +- src/servers/app/ServerBitmap.cpp | 75 +++++++++++-------- 3 files changed, 85 insertions(+), 81 deletions(-) diff --git a/headers/private/servers/app/ServerBitmap.h b/headers/private/servers/app/ServerBitmap.h index d86540fc83..77d40446cf 100644 --- a/headers/private/servers/app/ServerBitmap.h +++ b/headers/private/servers/app/ServerBitmap.h @@ -1,36 +1,19 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2001-2005, Haiku, Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// File Name: ServerBitmap.h -// Author: DarkWyrm -// Description: Bitmap class used inside the server -// -//------------------------------------------------------------------------------ +/* + * Copyright 2001-2005, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * DarkWyrm + */ #ifndef _SERVER_BITMAP_H_ #define _SERVER_BITMAP_H_ + #include #include #include + class BitmapManager; /*! @@ -43,14 +26,7 @@ class BitmapManager; */ class ServerBitmap { public: - ServerBitmap(BRect rect, - color_space space, - int32 flags, - int32 bytesperline = -1, - screen_id screen = B_MAIN_SCREEN_ID); - ServerBitmap(const ServerBitmap* bmp); - - virtual ~ServerBitmap(); + void Acquire(); /*! \brief Returns the area in which the buffer resides @@ -60,11 +36,11 @@ class ServerBitmap { */ inline area_id Area() const { return fArea; } - + // Returns the offset of the bitmap in its area inline int32 AreaOffset() const { return fOffset; } - + //! Returns the bitmap's buffer inline uint8* Bits() const { return fBuffer; } @@ -74,21 +50,21 @@ class ServerBitmap { inline BRect Bounds() const { return BRect(0, 0, fWidth - 1, fHeight - 1); } - + //! Returns the number of bytes in each row, including padding inline int32 BytesPerRow() const { return fBytesPerRow; } - + inline uint8 BitsPerPixel() const { return fBitsPerPixel; } - + inline color_space ColorSpace() const { return fSpace; } - + //! Returns the bitmap's width in pixels per row inline int32 Width() const { return fWidth; } - + //! Returns the bitmap's row count inline int32 Height() const { return fHeight; } @@ -99,32 +75,43 @@ class ServerBitmap { //! Returns the identifier token for the bitmap inline int32 Token() const { return fToken; } - + //! Does a shallow copy of the bitmap passed to it inline void ShallowCopy(const ServerBitmap *from); - + protected: friend class BitmapManager; friend class PicturePlayer; + ServerBitmap(BRect rect, + color_space space, + int32 flags, + int32 bytesperline = -1, + screen_id screen = B_MAIN_SCREEN_ID); + ServerBitmap(const ServerBitmap* bmp); + virtual ~ServerBitmap(); + //! used by the BitmapManager inline void _SetArea(area_id ID) - { fArea=ID; } - + { fArea = ID; } + //! used by the BitmapManager inline void _SetBuffer(void *ptr) - { fBuffer=(uint8*)ptr; } + { fBuffer = (uint8*)ptr; } + + bool _Release(); void _AllocateBuffer(); void _FreeBuffer(); - + void _HandleSpace(color_space space, int32 bytesperline = -1); bool fInitialized; area_id fArea; uint8* fBuffer; - + int32 fReferenceCount; + int32 fWidth; int32 fHeight; int32 fBytesPerRow; @@ -159,7 +146,7 @@ ServerBitmap::ShallowCopy(const ServerBitmap* from) { if (!from) return; - + fInitialized = from->fInitialized; fArea = from->fArea; fBuffer = from->fBuffer; diff --git a/src/servers/app/BitmapManager.cpp b/src/servers/app/BitmapManager.cpp index e070c941da..aeff27b93e 100644 --- a/src/servers/app/BitmapManager.cpp +++ b/src/servers/app/BitmapManager.cpp @@ -113,8 +113,12 @@ BitmapManager::CreateBitmap(BRect bounds, color_space space, int32 flags, void BitmapManager::DeleteBitmap(ServerBitmap *bitmap) { - BAutolock locker(fLock); + if (!bitmap->_Release()) { + // there are other references to this bitmap, we don't have to delete it yet + return; + } + BAutolock locker(fLock); if (!locker.IsLocked()) return; diff --git a/src/servers/app/ServerBitmap.cpp b/src/servers/app/ServerBitmap.cpp index 160f8c9dfa..408cf59b62 100644 --- a/src/servers/app/ServerBitmap.cpp +++ b/src/servers/app/ServerBitmap.cpp @@ -1,37 +1,20 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2001-2005, Haiku, Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// File Name: ServerBitmap.cpp -// Author: DarkWyrm -// Description: Bitmap class used by the server -// -//------------------------------------------------------------------------------ -#include +/* + * Copyright 2001-2005, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * DarkWyrm + */ -#include #include "ServerBitmap.h" +#include +#include + using std::nothrow; + /*! \brief Constructor called by the BitmapManager (only). \param rect Size of the bitmap. @@ -48,6 +31,7 @@ ServerBitmap::ServerBitmap(BRect rect, color_space space, : fInitialized(false), fArea(B_ERROR), fBuffer(NULL), + fReferenceCount(1), // WARNING: '1' is added to the width and height. // Same is done in FBBitmap subclass, so if you // modify here make sure to do the same under @@ -59,16 +43,17 @@ ServerBitmap::ServerBitmap(BRect rect, color_space space, fFlags(flags), fBitsPerPixel(0) // TODO: what about fToken and fOffset ?!? - { _HandleSpace(space, bytesPerLine); } + //! Copy constructor does not copy the buffer. ServerBitmap::ServerBitmap(const ServerBitmap* bmp) : fInitialized(false), fArea(B_ERROR), - fBuffer(NULL) + fBuffer(NULL), + fReferenceCount(1) // TODO: what about fToken and fOffset ?!? { if (bmp) { @@ -89,6 +74,7 @@ ServerBitmap::ServerBitmap(const ServerBitmap* bmp) } } + /*! \brief Empty. Defined for subclasses. */ @@ -98,6 +84,24 @@ ServerBitmap::~ServerBitmap() // instead of do that in every subclass ? } + +void +ServerBitmap::Acquire() +{ + atomic_add(&fReferenceCount, 1); +} + + +bool +ServerBitmap::_Release() +{ + if (atomic_add(&fReferenceCount, -1) == 1) + return true; + + return false; +} + + /*! \brief Internal function used by subclasses @@ -115,19 +119,21 @@ ServerBitmap::_AllocateBuffer(void) } } + /*! \brief Internal function used by subclasses Subclasses should call this to free the internal buffer. */ void -ServerBitmap::_FreeBuffer(void) +ServerBitmap::_FreeBuffer() { delete[] fBuffer; fBuffer = NULL; fInitialized = false; } + /*! \brief Internal function used to translate color space values to appropriate internal values. @@ -237,6 +243,10 @@ ServerBitmap::_HandleSpace(color_space space, int32 bytesPerRow) } } + +// #pragma mark - + + UtilityBitmap::UtilityBitmap(BRect rect, color_space space, int32 flags, int32 bytesperline, screen_id screen) @@ -245,6 +255,7 @@ UtilityBitmap::UtilityBitmap(BRect rect, color_space space, _AllocateBuffer(); } + UtilityBitmap::UtilityBitmap(const ServerBitmap* bmp) : ServerBitmap(bmp) { @@ -253,6 +264,7 @@ UtilityBitmap::UtilityBitmap(const ServerBitmap* bmp) memcpy(Bits(), bmp->Bits(), bmp->BitsLength()); } + UtilityBitmap::UtilityBitmap(const uint8* alreadyPaddedData, uint32 width, uint32 height, color_space format) @@ -263,6 +275,7 @@ UtilityBitmap::UtilityBitmap(const uint8* alreadyPaddedData, memcpy(Bits(), alreadyPaddedData, BitsLength()); } + UtilityBitmap::~UtilityBitmap() { _FreeBuffer();