From 60d3078585c786fd4d5ffc7bd6c7356300b0a04d Mon Sep 17 00:00:00 2001 From: X512 Date: Thu, 27 Aug 2020 15:50:59 +0200 Subject: [PATCH] app_server memory management fixes: use BReference Use BReference for more automated reference counting in app_server, fixing some use-after-free and other problems. Extracted from https://review.haiku-os.org/c/haiku/+/2695 Change-Id: I141bb248229405896b29feff3338447f7257b0b4 Reviewed-on: https://review.haiku-os.org/c/haiku/+/3175 Reviewed-by: Adrien Destugues --- src/servers/app/BitmapManager.cpp | 8 +- src/servers/app/Canvas.cpp | 18 +-- src/servers/app/ClientMemoryAllocator.cpp | 5 +- src/servers/app/ClientMemoryAllocator.h | 3 +- src/servers/app/CursorManager.cpp | 22 ++-- src/servers/app/DrawState.cpp | 6 +- src/servers/app/EventDispatcher.cpp | 17 --- src/servers/app/EventDispatcher.h | 7 -- src/servers/app/Layer.cpp | 42 +++---- src/servers/app/OffscreenServerWindow.cpp | 3 +- src/servers/app/OffscreenServerWindow.h | 4 +- src/servers/app/PictureBoundingBoxPlayer.cpp | 22 ++-- src/servers/app/ReferenceCounting.h | 55 --------- src/servers/app/ServerApp.cpp | 90 ++++---------- src/servers/app/ServerApp.h | 12 +- src/servers/app/ServerCursor.cpp | 2 +- src/servers/app/ServerFont.cpp | 30 ++--- src/servers/app/ServerFont.h | 3 +- src/servers/app/ServerPicture.cpp | 68 ++++------- src/servers/app/ServerPicture.h | 13 +- src/servers/app/ServerWindow.cpp | 62 +++------- src/servers/app/View.cpp | 101 ++++++---------- src/servers/app/View.h | 23 ++-- src/servers/app/drawing/AlphaMask.cpp | 7 +- .../app/drawing/BitmapDrawingEngine.cpp | 22 ++-- src/servers/app/drawing/BitmapDrawingEngine.h | 9 +- src/servers/app/drawing/HWInterface.cpp | 113 ++++++------------ src/servers/app/drawing/HWInterface.h | 19 +-- src/servers/app/font/FontCache.cpp | 17 +-- src/servers/app/font/FontCache.h | 2 +- src/servers/app/font/FontFamily.cpp | 1 - src/servers/app/font/FontManager.cpp | 2 +- src/servers/app/font/FontManager.h | 3 +- src/servers/app/font/FontStyle.h | 4 +- 34 files changed, 281 insertions(+), 534 deletions(-) delete mode 100644 src/servers/app/ReferenceCounting.h diff --git a/src/servers/app/BitmapManager.cpp b/src/servers/app/BitmapManager.cpp index 347289748b..24d93de327 100644 --- a/src/servers/app/BitmapManager.cpp +++ b/src/servers/app/BitmapManager.cpp @@ -197,19 +197,17 @@ BitmapManager::CloneFromClient(area_id clientArea, int32 areaOffset, BAutolock locker(fLock); if (!locker.IsLocked()) return NULL; - ServerBitmap* bitmap = new(std::nothrow) ServerBitmap(bounds, space, flags, - bytesPerRow); + BReference bitmap(new(std::nothrow) ServerBitmap(bounds, space, flags, + bytesPerRow), true); if (bitmap == NULL) return NULL; ClonedAreaMemory* memory = new(std::nothrow) ClonedAreaMemory; if (memory == NULL) { - delete bitmap; return NULL; } int8* buffer = (int8*)memory->Clone(clientArea, areaOffset); if (buffer == NULL) { - delete bitmap; delete memory; return NULL; } @@ -217,7 +215,7 @@ BitmapManager::CloneFromClient(area_id clientArea, int32 areaOffset, bitmap->fMemory = memory; bitmap->fBuffer = memory->Address(); bitmap->fToken = gTokenSpace.NewToken(kBitmapToken, bitmap); - return bitmap; + return bitmap.Detach(); } diff --git a/src/servers/app/Canvas.cpp b/src/servers/app/Canvas.cpp index 881eaaabce..acab142141 100644 --- a/src/servers/app/Canvas.cpp +++ b/src/servers/app/Canvas.cpp @@ -237,15 +237,16 @@ Canvas::ScreenToPenTransform() const GCC_2_NRV(transform) void -Canvas::BlendLayer(Layer* layer) +Canvas::BlendLayer(Layer* layerPtr) { + BReference layer(layerPtr, true); + if (layer->Opacity() == 255) { layer->Play(this); - layer->ReleaseReference(); return; } - UtilityBitmap* layerBitmap = layer->RenderToBitmap(this); + BReference layerBitmap(layer->RenderToBitmap(this), true); if (layerBitmap == NULL) return; @@ -259,15 +260,11 @@ Canvas::BlendLayer(Layer* layer) fDrawState->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_COMPOSITE); fDrawState->SetTransformEnabled(false); - AlphaMask* mask = new(std::nothrow) UniformAlphaMask(layer->Opacity()); - if (mask == NULL) { - layerBitmap->ReleaseReference(); - layer->ReleaseReference(); + BReference mask(new(std::nothrow) UniformAlphaMask(layer->Opacity()), true); + if (mask == NULL) return; - } SetAlphaMask(mask); - mask->ReleaseReference(); ResyncDrawState(); GetDrawingEngine()->DrawBitmap(layerBitmap, layerBitmap->Bounds(), @@ -277,9 +274,6 @@ Canvas::BlendLayer(Layer* layer) PopState(); ResyncDrawState(); - - layerBitmap->ReleaseReference(); - layer->ReleaseReference(); } diff --git a/src/servers/app/ClientMemoryAllocator.cpp b/src/servers/app/ClientMemoryAllocator.cpp index cb07609bc3..182bcf601b 100644 --- a/src/servers/app/ClientMemoryAllocator.cpp +++ b/src/servers/app/ClientMemoryAllocator.cpp @@ -327,7 +327,7 @@ ClientMemory::~ClientMemory() if (fAllocator != NULL) { if (fBlock != NULL) fAllocator->Free(fBlock); - fAllocator->ReleaseReference(); + fAllocator.Unset(); } } @@ -336,8 +336,7 @@ void* ClientMemory::Allocate(ClientMemoryAllocator* allocator, size_t size, bool& newArea) { - fAllocator = allocator; - fAllocator->AcquireReference(); + fAllocator.SetTo(allocator, false); return fAllocator->Allocate(size, &fBlock, newArea); } diff --git a/src/servers/app/ClientMemoryAllocator.h b/src/servers/app/ClientMemoryAllocator.h index 283ab8da5b..799ebfa219 100644 --- a/src/servers/app/ClientMemoryAllocator.h +++ b/src/servers/app/ClientMemoryAllocator.h @@ -83,7 +83,8 @@ public: virtual uint32 AreaOffset(); private: - ClientMemoryAllocator* fAllocator; + BReference + fAllocator; block* fBlock; }; diff --git a/src/servers/app/CursorManager.cpp b/src/servers/app/CursorManager.cpp index 35cac756db..3b8355e0c5 100644 --- a/src/servers/app/CursorManager.cpp +++ b/src/servers/app/CursorManager.cpp @@ -97,8 +97,11 @@ CursorManager::CursorManager() //! Does all the teardown CursorManager::~CursorManager() { - for (int32 i = 0; i < fCursorList.CountItems(); i++) - delete (ServerCursor*)fCursorList.ItemAtFast(i); + for (int32 i = 0; i < fCursorList.CountItems(); i++) { + ServerCursor* cursor = ((ServerCursor*)fCursorList.ItemAtFast(i)); + cursor->fManager = NULL; + cursor->ReleaseReference(); + } } @@ -108,23 +111,20 @@ CursorManager::CreateCursor(team_id clientTeam, const uint8* cursorData) if (!Lock()) return NULL; - ServerCursor* cursor = _FindCursor(clientTeam, cursorData); + ServerCursorReference cursor(_FindCursor(clientTeam, cursorData), false); if (!cursor) { - cursor = new (std::nothrow) ServerCursor(cursorData); + cursor.SetTo(new (std::nothrow) ServerCursor(cursorData), true); if (cursor) { cursor->SetOwningTeam(clientTeam); - if (AddCursor(cursor) < B_OK) { - delete cursor; + if (AddCursor(cursor) < B_OK) cursor = NULL; - } } - } else - cursor->AcquireReference(); + } Unlock(); - return cursor; + return cursor.Detach(); } @@ -408,7 +408,7 @@ CursorManager::_LoadCursor(ServerCursor*& cursorMember, const CursorSet& set, if (set.FindCursor(id, &cursor) == B_OK) { int32 index = fCursorList.IndexOf(cursorMember); if (index >= 0) { - ServerCursor* items = reinterpret_cast( + ServerCursor** items = reinterpret_cast( fCursorList.Items()); items[index] = cursor; } diff --git a/src/servers/app/DrawState.cpp b/src/servers/app/DrawState.cpp index f9486a2112..51c939e9fe 100644 --- a/src/servers/app/DrawState.cpp +++ b/src/servers/app/DrawState.cpp @@ -545,12 +545,10 @@ DrawState::ClipToShape(shape_data* shape, bool inverse) if (!fCombinedTransform.IsIdentity()) fCombinedTransform.Apply(shape->ptList, shape->ptCount); - AlphaMask* const mask = ShapeAlphaMask::Create(GetAlphaMask(), *shape, - BPoint(0, 0), inverse); + BReference const mask(ShapeAlphaMask::Create(GetAlphaMask(), *shape, + BPoint(0, 0), inverse), true); SetAlphaMask(mask); - if (mask != NULL) - mask->ReleaseReference(); } diff --git a/src/servers/app/EventDispatcher.cpp b/src/servers/app/EventDispatcher.cpp index 9c8fb902f6..f1e2a5f6bd 100644 --- a/src/servers/app/EventDispatcher.cpp +++ b/src/servers/app/EventDispatcher.cpp @@ -247,7 +247,6 @@ EventDispatcher::EventDispatcher() fLastButtons(0), fLastUpdate(system_time()), fDraggingMessage(false), - fDragBitmap(NULL), fCursorLock("cursor loop lock"), fHWInterface(NULL), fDesktop(NULL) @@ -612,21 +611,9 @@ EventDispatcher::SetDragMessage(BMessage& message, if (fLastButtons == 0) { // mouse buttons has already been released or was never pressed - if (bitmap != NULL) - bitmap->ReleaseReference(); return; } - if (fDragBitmap != bitmap) { - if (fDragBitmap) - fDragBitmap->ReleaseReference(); - - fDragBitmap = bitmap; - - if (fDragBitmap != NULL) - fDragBitmap->AcquireReference(); - } - fHWInterface->SetDragBitmap(bitmap, offsetFromCursor); fDragMessage = message; @@ -757,10 +744,6 @@ EventDispatcher::_DeliverDragMessage() fDraggingMessage = false; fHWInterface->SetDragBitmap(NULL, B_ORIGIN); - if (fDragBitmap != NULL) { - fDragBitmap->ReleaseReference(); - fDragBitmap = NULL; - } } diff --git a/src/servers/app/EventDispatcher.h b/src/servers/app/EventDispatcher.h index aff524b6a9..c74bb516b1 100644 --- a/src/servers/app/EventDispatcher.h +++ b/src/servers/app/EventDispatcher.h @@ -150,13 +150,6 @@ class EventDispatcher : public BLocker { BMessage fDragMessage; bool fDraggingMessage; BPoint fDragOffset; - ServerBitmap* fDragBitmap; - // NOTE: unfortunately, the EventDispatcher - // has to know what a ServerBitmap is... - // otherwise, linking the libs in the - // testenvironment is problematic, because - // the alternative is that HWInterface knows - // about BitmapManager BLocker fCursorLock; HWInterface* fHWInterface; diff --git a/src/servers/app/Layer.cpp b/src/servers/app/Layer.cpp index 4fa8868a2e..b07a398ac4 100644 --- a/src/servers/app/Layer.cpp +++ b/src/servers/app/Layer.cpp @@ -23,8 +23,7 @@ public: fDrawingEngine(drawingEngine), fBitmapBounds(bitmapBounds) { - delete fDrawState; - fDrawState = drawState; + fDrawState.SetTo(drawState); } virtual DrawingEngine* GetDrawingEngine() const @@ -43,7 +42,7 @@ public: virtual void ResyncDrawState() { - fDrawingEngine->SetDrawState(fDrawState); + fDrawingEngine->SetDrawState(fDrawState.Get()); } virtual void UpdateCurrentDrawingRegion() @@ -104,10 +103,7 @@ Layer::PushLayer(Layer* layer) Layer* Layer::PopLayer() { - Layer* const previousLayer = static_cast(PopPicture()); - if (previousLayer != NULL) - previousLayer->ReleaseReference(); - return previousLayer; + return static_cast(PopPicture()); } @@ -120,16 +116,15 @@ Layer::RenderToBitmap(Canvas* canvas) fLeftTopOffset = boundingBox.LeftTop(); - UtilityBitmap* const layerBitmap = _AllocateBitmap(boundingBox); + BReference layerBitmap(_AllocateBitmap(boundingBox), true); if (layerBitmap == NULL) return NULL; BitmapHWInterface layerInterface(layerBitmap); - DrawingEngine* const layerEngine = layerInterface.CreateDrawingEngine(); - if (layerEngine == NULL) { - layerBitmap->ReleaseReference(); + ObjectDeleter const layerEngine(layerInterface.CreateDrawingEngine()); + if (layerEngine.Get() == NULL) return NULL; - } + layerEngine->SetRendererOffset(boundingBox.left, boundingBox.top); // Drawing commands of the layer's picture use coordinates in the // coordinate space of the underlying canvas. The coordinate origin @@ -141,7 +136,7 @@ Layer::RenderToBitmap(Canvas* canvas) // Painter), to prevent this origin from being further transformed by // e.g. scaling. - LayerCanvas layerCanvas(layerEngine, canvas->CurrentState(), boundingBox); + LayerCanvas layerCanvas(layerEngine.Get(), canvas->DetachDrawState(), boundingBox); AlphaMask* const mask = layerCanvas.GetAlphaMask(); IntPoint oldOffset; @@ -150,8 +145,8 @@ Layer::RenderToBitmap(Canvas* canvas) oldOffset = mask->SetCanvasGeometry(IntPoint(0, 0), boundingBox); } - canvas->CurrentState()->SetDrawingMode(B_OP_ALPHA); - canvas->CurrentState()->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_COMPOSITE); + layerCanvas.CurrentState()->SetDrawingMode(B_OP_ALPHA); + layerCanvas.CurrentState()->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_COMPOSITE); layerCanvas.ResyncDrawState(); // Apply state to the new drawing engine of the layer canvas @@ -174,14 +169,12 @@ Layer::RenderToBitmap(Canvas* canvas) layerCanvas.ResyncDrawState(); } - canvas->SetDrawState(layerCanvas.CurrentState()); + canvas->SetDrawState(layerCanvas.DetachDrawState()); // Update state in canvas (the top-of-stack state could be a different // state instance now, if the picture commands contained push/pop // commands) - delete layerEngine; - - return layerBitmap; + return layerBitmap.Detach(); } @@ -225,15 +218,14 @@ Layer::_DetermineBoundingBox(Canvas* canvas) UtilityBitmap* Layer::_AllocateBitmap(const BRect& bounds) { - UtilityBitmap* const layerBitmap = new(std::nothrow) UtilityBitmap(bounds, - B_RGBA32, 0); + BReference layerBitmap(new(std::nothrow) UtilityBitmap(bounds, + B_RGBA32, 0), true); if (layerBitmap == NULL) return NULL; - if (!layerBitmap->IsValid()) { - delete layerBitmap; + if (!layerBitmap->IsValid()) return NULL; - } + memset(layerBitmap->Bits(), 0, layerBitmap->BitsLength()); - return layerBitmap; + return layerBitmap.Detach(); } diff --git a/src/servers/app/OffscreenServerWindow.cpp b/src/servers/app/OffscreenServerWindow.cpp index 102ed01e95..f4b2426ddc 100644 --- a/src/servers/app/OffscreenServerWindow.cpp +++ b/src/servers/app/OffscreenServerWindow.cpp @@ -17,14 +17,13 @@ OffscreenServerWindow::OffscreenServerWindow(const char *title, ServerApp *app, port_id clientPort, port_id looperPort, int32 handlerID, ServerBitmap* bitmap) : ServerWindow(title, app, clientPort, looperPort, handlerID), - fBitmap(bitmap) + fBitmap(bitmap, true) { } OffscreenServerWindow::~OffscreenServerWindow() { - fBitmap->ReleaseReference(); } diff --git a/src/servers/app/OffscreenServerWindow.h b/src/servers/app/OffscreenServerWindow.h index 34e3d522f3..df756d2875 100644 --- a/src/servers/app/OffscreenServerWindow.h +++ b/src/servers/app/OffscreenServerWindow.h @@ -19,7 +19,7 @@ public: int32 handlerID, ServerBitmap* bitmap); virtual ~OffscreenServerWindow(); - // util methods. + // util methods. virtual void SendMessageToClient(const BMessage* msg, int32 target = B_NULL_TOKEN, bool usePreferred = false) const; @@ -29,7 +29,7 @@ public: uint32 workspace); private: - ServerBitmap* fBitmap; + BReference fBitmap; }; #endif // OFFSCREEN_SERVER_WINDOW_H diff --git a/src/servers/app/PictureBoundingBoxPlayer.cpp b/src/servers/app/PictureBoundingBoxPlayer.cpp index 27fdaa51e6..7c324b7f60 100644 --- a/src/servers/app/PictureBoundingBoxPlayer.cpp +++ b/src/servers/app/PictureBoundingBoxPlayer.cpp @@ -25,6 +25,7 @@ #include "View.h" #include "Window.h" +#include #include #include #include @@ -60,25 +61,27 @@ public: ~State() { - delete fDrawState; } DrawState* GetDrawState() { - return fDrawState; + return fDrawState.Get(); } void PushDrawState() { - DrawState* nextState = fDrawState->PushState(); - if (nextState != NULL) - fDrawState = nextState; + DrawState* previousState = fDrawState.Detach(); + DrawState* newState = previousState->PushState(); + if (newState == NULL) + newState = previousState; + + fDrawState.SetTo(newState); } void PopDrawState() { if (fDrawState->PreviousState() != NULL) - fDrawState = fDrawState->PopState(); + fDrawState.SetTo(fDrawState->PopState()); } SimpleTransform PenToLocalTransform() const @@ -130,7 +133,8 @@ private: private: - DrawState* fDrawState; + ObjectDeleter + fDrawState; BRect* fBoundingBox; }; @@ -841,13 +845,13 @@ PictureBoundingBoxPlayer::Play(ServerPicture* picture, { State state(drawState, outBoundingBox); - BMallocIO* mallocIO = dynamic_cast(picture->fData); + BMallocIO* mallocIO = dynamic_cast(picture->fData.Get()); if (mallocIO == NULL) return; BPrivate::PicturePlayer player(mallocIO->Buffer(), mallocIO->BufferLength(), ServerPicture::PictureList::Private( - picture->fPictures).AsBList()); + picture->fPictures.Get()).AsBList()); player.Play(kPictureBoundingBoxPlayerCallbacks, sizeof(kPictureBoundingBoxPlayerCallbacks), &state); } diff --git a/src/servers/app/ReferenceCounting.h b/src/servers/app/ReferenceCounting.h deleted file mode 100644 index 2b8f5435cc..0000000000 --- a/src/servers/app/ReferenceCounting.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2001-2005, Haiku. - * Distributed under the terms of the MIT License. - * - * Authors: - * DarkWyrm - * Axel Dörfler, axeld@pinc-software.de - */ -#ifndef REFERENCE_COUNTING_H -#define REFERENCE_COUNTING_H - - -#include - - -/*! - \class ReferenceCounting ReferenceCounting.h - \brief Base class for reference counting objects - - ReferenceCounting objects track dependencies upon a particular object. In this way, - it is possible to ensure that a shared resource is not deleted if something else - needs it. How the dependency tracking is done largely depends on the child class. -*/ -class ReferenceCounting { - public: - ReferenceCounting() - : fReferenceCount(1) {} - virtual ~ReferenceCounting() {} - - inline void Acquire(); - inline bool Release(); - - private: - int32 fReferenceCount; -}; - - -inline void -ReferenceCounting::Acquire() -{ - atomic_add(&fReferenceCount, 1); -} - -inline bool -ReferenceCounting::Release() -{ - if (atomic_add(&fReferenceCount, -1) == 1) { - delete this; - return true; - } - - return false; -} - -#endif /* REFERENCE_COUNTING_H */ diff --git a/src/servers/app/ServerApp.cpp b/src/servers/app/ServerApp.cpp index 1bf20a082f..198dc2fb87 100644 --- a/src/servers/app/ServerApp.cpp +++ b/src/servers/app/ServerApp.cpp @@ -105,7 +105,7 @@ ServerApp::ServerApp(Desktop* desktop, port_id clientReplyPort, fViewCursor(NULL), fCursorHideLevel(0), fIsActive(false), - fMemoryAllocator(new (std::nothrow) ClientMemoryAllocator(this)) + fMemoryAllocator(new (std::nothrow) ClientMemoryAllocator(this), true) { if (fSignature == "") fSignature = "application/no-signature"; @@ -205,8 +205,6 @@ ServerApp::~ServerApp() fPictureMap.begin()->second->SetOwner(NULL); fDesktop->GetCursorManager().DeleteCursors(fClientTeam); - if (fMemoryAllocator != NULL) - fMemoryAllocator->ReleaseReference(); STRACE(("ServerApp %s::~ServerApp(): Exiting\n", Signature())); } @@ -294,15 +292,7 @@ ServerApp::Activate(bool value) void ServerApp::SetCurrentCursor(ServerCursor* cursor) { - if (fViewCursor != cursor) { - if (fViewCursor) - fViewCursor->ReleaseReference(); - - fViewCursor = cursor; - - if (fViewCursor) - fViewCursor->AcquireReference(); - } + fViewCursor.SetTo(cursor, false); fDesktop->SetCursor(CurrentCursor()); } @@ -417,16 +407,16 @@ ServerApp::GetBitmap(int32 token) const ServerPicture* ServerApp::CreatePicture(const ServerPicture* original) { - ServerPicture* picture; + BReference picture; if (original != NULL) - picture = new(std::nothrow) ServerPicture(*original); + picture.SetTo(new(std::nothrow) ServerPicture(*original), true); else - picture = new(std::nothrow) ServerPicture(); + picture.SetTo(new(std::nothrow) ServerPicture(), true); if (picture != NULL && !picture->SetOwner(this)) - picture->ReleaseReference(); + return NULL; - return picture; + return picture.Detach(); } @@ -457,7 +447,7 @@ ServerApp::AddPicture(ServerPicture* picture) ASSERT(picture->Owner() == NULL); try { - fPictureMap.insert(std::make_pair(picture->Token(), picture)); + fPictureMap.insert(std::make_pair(picture->Token(), BReference(picture, false))); } catch (std::bad_alloc& exception) { return false; } @@ -475,7 +465,6 @@ ServerApp::RemovePicture(ServerPicture* picture) ASSERT(picture->Owner() == this); fPictureMap.erase(picture->Token()); - picture->ReleaseReference(); } @@ -750,7 +739,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) // 3) int32 area pointer offset used to calculate fBasePtr // First, let's attempt to allocate the bitmap - ServerBitmap* bitmap = NULL; + BReference bitmap; uint8 allocationFlags = kAllocator; BRect frame; @@ -766,9 +755,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) if (link.Read(&screenID) == B_OK) { // TODO: choose the right HWInterface with regards to the // screenID - bitmap = gBitmapManager->CreateBitmap(fMemoryAllocator, + bitmap.SetTo(gBitmapManager->CreateBitmap(fMemoryAllocator, *fDesktop->HWInterface(), frame, colorSpace, flags, - bytesPerRow, screenID, &allocationFlags); + bytesPerRow, screenID, &allocationFlags), true); } STRACE(("ServerApp %s: Create Bitmap (%.1fx%.1f)\n", @@ -785,9 +774,6 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) if ((allocationFlags & kFramebuffer) != 0) fLink.Attach(bitmap->BytesPerRow()); } else { - if (bitmap != NULL) - bitmap->ReleaseReference(); - fLink.StartMessage(B_NO_MEMORY); } @@ -828,15 +814,13 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) if (link.Read(&token) != B_OK) break; - ServerBitmap* bitmap = GetBitmap(token); + BReference bitmap(GetBitmap(token), true); if (bitmap != NULL) { STRACE(("ServerApp %s: Get overlay restrictions for bitmap " "%" B_PRId32 "\n", Signature(), token)); status = fDesktop->HWInterface()->GetOverlayRestrictions( bitmap->Overlay(), &restrictions); - - bitmap->ReleaseReference(); } fLink.StartMessage(status); @@ -866,7 +850,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) case AS_RECONNECT_BITMAP: { // First, let's attempt to allocate the bitmap - ServerBitmap* bitmap = NULL; + BReference bitmap; BRect frame; color_space colorSpace; @@ -885,8 +869,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) if (link.Read(&areaOffset) == B_OK) { // TODO: choose the right HWInterface with regards to the // screenID - bitmap = gBitmapManager->CloneFromClient(clientArea, areaOffset, - frame, colorSpace, flags, bytesPerRow); + bitmap.SetTo(gBitmapManager->CloneFromClient(clientArea, areaOffset, + frame, colorSpace, flags, bytesPerRow), true); } if (bitmap != NULL && _AddBitmap(bitmap)) { @@ -896,9 +880,6 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) fLink.Attach(bitmap->Area()); } else { - if (bitmap != NULL) - bitmap->ReleaseReference(); - fLink.StartMessage(B_NO_MEMORY); } @@ -914,7 +895,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) STRACE(("ServerApp %s: Create Picture\n", Signature())); status_t status = B_NO_MEMORY; - ServerPicture* picture = CreatePicture(); + BReference picture(CreatePicture()); if (picture != NULL) { int32 subPicturesCount = 0; link.Read(&subPicturesCount); @@ -956,19 +937,17 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) { STRACE(("ServerApp %s: Clone Picture\n", Signature())); int32 token; - ServerPicture* original = NULL; + BReference original; if (link.Read(&token) == B_OK) - original = GetPicture(token); + original.SetTo(GetPicture(token), true); if (original != NULL) { - ServerPicture* cloned = CreatePicture(original); + BReference cloned(CreatePicture(original), true); if (cloned != NULL) { fLink.StartMessage(B_OK); fLink.Attach(cloned->Token()); } else fLink.StartMessage(B_NO_MEMORY); - - original->ReleaseReference(); } else fLink.StartMessage(B_BAD_VALUE); @@ -981,11 +960,10 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) STRACE(("ServerApp %s: Download Picture\n", Signature())); int32 token; link.Read(&token); - ServerPicture* picture = GetPicture(token); + BReference picture(GetPicture(token), true); if (picture != NULL) { picture->ExportData(fLink); // ExportData() calls StartMessage() already - picture->ReleaseReference(); } else fLink.StartMessage(B_ERROR); @@ -1110,17 +1088,11 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) if (!fDesktop->GetCursorManager().Lock()) break; - ServerCursor* oldCursor = fAppCursor; - fAppCursor = fDesktop->GetCursorManager().FindCursor(token); - if (fAppCursor != NULL) - fAppCursor->AcquireReference(); + fAppCursor.SetTo(fDesktop->GetCursorManager().FindCursor(token), false); if (_HasWindowUnderMouse()) fDesktop->SetCursor(CurrentCursor()); - if (oldCursor != NULL) - oldCursor->ReleaseReference(); - fDesktop->GetCursorManager().Unlock(); if (sync) { @@ -1140,13 +1112,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) break; if (fDesktop->GetCursorManager().Lock()) { - ServerCursor* cursor = fDesktop->GetCursorManager().FindCursor( - info.cursorToken); - // If we found a cursor, make sure it doesn't go away. If we - // get a NULL cursor, it probably means we are supposed to use - // the system default cursor. - if (cursor != NULL) - cursor->AcquireReference(); + BReference cursor(fDesktop->GetCursorManager().FindCursor( + info.cursorToken), false); fDesktop->GetCursorManager().Unlock(); @@ -1174,10 +1141,6 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) } fDesktop->UnlockAllWindows(); - - // Release the temporary reference. - if (cursor != NULL) - cursor->ReleaseReference(); } if (info.sync) { @@ -3190,14 +3153,13 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) bool success = false; - ServerBitmap* bitmap = GetBitmap(token); + BReference bitmap(GetBitmap(token), true); if (bitmap != NULL) { if (fDesktop->GetDrawingEngine()->LockExclusiveAccess()) { success = fDesktop->GetDrawingEngine()->ReadBitmap(bitmap, drawCursor, bounds) == B_OK; fDesktop->GetDrawingEngine()->UnlockExclusiveAccess(); } - bitmap->ReleaseReference(); } if (success) @@ -3552,7 +3514,7 @@ ServerApp::_AddBitmap(ServerBitmap* bitmap) BAutolock _(fMapLocker); try { - fBitmapMap.insert(std::make_pair(bitmap->Token(), bitmap)); + fBitmapMap.insert(std::make_pair(bitmap->Token(), BReference(bitmap, false))); } catch (std::bad_alloc& exception) { return false; } @@ -3569,8 +3531,6 @@ ServerApp::_DeleteBitmap(ServerBitmap* bitmap) gBitmapManager->BitmapRemoved(bitmap); fBitmapMap.erase(bitmap->Token()); - - bitmap->ReleaseReference(); } diff --git a/src/servers/app/ServerApp.h b/src/servers/app/ServerApp.h index 433ea472f6..3908ef32b1 100644 --- a/src/servers/app/ServerApp.h +++ b/src/servers/app/ServerApp.h @@ -115,8 +115,8 @@ private: ServerPicture* _FindPicture(int32 token) const; private: - typedef std::map BitmapMap; - typedef std::map PictureMap; + typedef std::map > BitmapMap; + typedef std::map > PictureMap; port_id fMessagePort; port_id fClientReplyPort; @@ -150,14 +150,16 @@ private: BitmapMap fBitmapMap; PictureMap fPictureMap; - ServerCursor* fAppCursor; - ServerCursor* fViewCursor; + BReference + fAppCursor; + BReference + fViewCursor; int32 fCursorHideLevel; // 0 = cursor visible bool fIsActive; - ClientMemoryAllocator* fMemoryAllocator; + BReference fMemoryAllocator; }; diff --git a/src/servers/app/ServerCursor.cpp b/src/servers/app/ServerCursor.cpp index 22039cf414..1b97fb4da3 100644 --- a/src/servers/app/ServerCursor.cpp +++ b/src/servers/app/ServerCursor.cpp @@ -195,7 +195,7 @@ ServerCursor::AttachedToManager(CursorManager* manager) void ServerCursor::LastReferenceReleased() { - if (fManager != NULL && fManager->RemoveCursor(this)) + if (fManager == NULL || fManager->RemoveCursor(this)) delete this; } diff --git a/src/servers/app/ServerFont.cpp b/src/servers/app/ServerFont.cpp index fab502af5b..834a3e6167 100644 --- a/src/servers/app/ServerFont.cpp +++ b/src/servers/app/ServerFont.cpp @@ -130,7 +130,7 @@ is_white_space(uint32 charCode) ServerFont::ServerFont(FontStyle& style, float size, float rotation, float shear, float falseBoldWidth, uint16 flags, uint8 spacing) : - fStyle(&style), + fStyle(&style, false), fSize(size), fRotation(rotation), fShear(shear), @@ -142,7 +142,6 @@ ServerFont::ServerFont(FontStyle& style, float size, float rotation, fFace(style.Face()), fEncoding(B_UNICODE_UTF8) { - fStyle->Acquire(); } @@ -171,7 +170,6 @@ ServerFont::ServerFont(const ServerFont &font) */ ServerFont::~ServerFont() { - fStyle->Release(); } @@ -252,14 +250,7 @@ void ServerFont::SetStyle(FontStyle* style) { if (style && style != fStyle) { - // detach from old style - if (fStyle != NULL) - fStyle->Release(); - - // attach to new style - fStyle = style; - - fStyle->Acquire(); + fStyle.SetTo(style, false); fFace = fStyle->Face(); fDirection = fStyle->Direction(); @@ -278,12 +269,10 @@ ServerFont::SetStyle(FontStyle* style) status_t ServerFont::SetFamilyAndStyle(uint16 familyID, uint16 styleID) { - FontStyle* style = NULL; + BReference style; if (gFontManager->Lock()) { - style = gFontManager->GetStyle(familyID, styleID); - if (style != NULL) - style->Acquire(); + style.SetTo(gFontManager->GetStyle(familyID, styleID), false); gFontManager->Unlock(); } @@ -292,7 +281,6 @@ ServerFont::SetFamilyAndStyle(uint16 familyID, uint16 styleID) return B_ERROR; SetStyle(style); - style->Release(); return B_OK; } @@ -323,18 +311,17 @@ ServerFont::SetFace(uint16 face) // FontStyle class takes care of mapping the font style name to the Be // API face flags in FontStyle::_TranslateStyleToFace(). - FontStyle* style = NULL; + BReference style; uint16 familyID = FamilyID(); if (gFontManager->Lock()) { int32 count = gFontManager->CountStyles(familyID); for (int32 i = 0; i < count; i++) { - style = gFontManager->GetStyleByIndex(familyID, i); + style.SetTo(gFontManager->GetStyleByIndex(familyID, i), false); if (style == NULL) break; - if (style->Face() == face) { - style->Acquire(); + if (style->Face() == face) break; - } else + else style = NULL; } @@ -345,7 +332,6 @@ ServerFont::SetFace(uint16 face) return B_ERROR; SetStyle(style); - style->Release(); return B_OK; } diff --git a/src/servers/app/ServerFont.h b/src/servers/app/ServerFont.h index b5a5e7d702..3a782a2fe3 100644 --- a/src/servers/app/ServerFont.h +++ b/src/servers/app/ServerFont.h @@ -173,7 +173,8 @@ protected: bool shear) const; void PutTransformedFace(FT_Face face) const; - FontStyle* fStyle; + BReference + fStyle; float fSize; float fRotation; float fShear; diff --git a/src/servers/app/ServerPicture.cpp b/src/servers/app/ServerPicture.cpp index 10d61edd4f..0756fe36ad 100644 --- a/src/servers/app/ServerPicture.cpp +++ b/src/servers/app/ServerPicture.cpp @@ -590,7 +590,7 @@ draw_picture(void* _canvas, const BPoint& where, int32 token) { Canvas* const canvas = reinterpret_cast(_canvas); - ServerPicture* picture = canvas->GetPicture(token); + BReference picture(canvas->GetPicture(token), true); if (picture != NULL) { canvas->PushState(); canvas->SetDrawingOrigin(where); @@ -600,7 +600,6 @@ draw_picture(void* _canvas, const BPoint& where, int32 token) canvas->PopState(); canvas->PopState(); - picture->ReleaseReference(); } } @@ -630,19 +629,15 @@ clip_to_picture(void* _canvas, int32 pictureToken, const BPoint& where, { Canvas* const canvas = reinterpret_cast(_canvas); - ServerPicture* picture = canvas->GetPicture(pictureToken); + BReference picture(canvas->GetPicture(pictureToken), true); if (picture == NULL) return; - AlphaMask* mask = new(std::nothrow) PictureAlphaMask(canvas->GetAlphaMask(), - picture, *canvas->CurrentState(), where, clipToInverse); + BReference mask(new(std::nothrow) PictureAlphaMask(canvas->GetAlphaMask(), + picture, *canvas->CurrentState(), where, clipToInverse), true); canvas->SetAlphaMask(mask); canvas->CurrentState()->GetAlphaMask()->SetCanvasGeometry(BPoint(0, 0), canvas->Bounds()); canvas->ResyncDrawState(); - if (mask != NULL) - mask->ReleaseReference(); - - picture->ReleaseReference(); } @@ -1082,14 +1077,12 @@ static const BPrivate::picture_player_callbacks kPicturePlayerCallbacks = { ServerPicture::ServerPicture() : fFile(NULL), - fPictures(NULL), - fPushed(NULL), fOwner(NULL) { fToken = gTokenSpace.NewToken(kPictureToken, this); - fData = new(std::nothrow) BMallocIO(); + fData.SetTo(new(std::nothrow) BMallocIO()); - PictureDataWriter::SetTo(fData); + PictureDataWriter::SetTo(fData.Get()); } @@ -1097,8 +1090,6 @@ ServerPicture::ServerPicture(const ServerPicture& picture) : fFile(NULL), fData(NULL), - fPictures(NULL), - fPushed(NULL), fOwner(NULL) { fToken = gTokenSpace.NewToken(kPictureToken, this); @@ -1107,7 +1098,7 @@ ServerPicture::ServerPicture(const ServerPicture& picture) if (mallocIO == NULL) return; - fData = mallocIO; + fData.SetTo(mallocIO); const off_t size = picture.DataLength(); if (mallocIO->SetSize(size) < B_OK) @@ -1116,7 +1107,7 @@ ServerPicture::ServerPicture(const ServerPicture& picture) picture.fData->ReadAt(0, const_cast(mallocIO->Buffer()), size); - PictureDataWriter::SetTo(fData); + PictureDataWriter::SetTo(fData.Get()); } @@ -1124,26 +1115,24 @@ ServerPicture::ServerPicture(const char* fileName, int32 offset) : fFile(NULL), fData(NULL), - fPictures(NULL), - fPushed(NULL), fOwner(NULL) { fToken = gTokenSpace.NewToken(kPictureToken, this); - fFile = new(std::nothrow) BFile(fileName, B_READ_WRITE); - if (fFile == NULL) + fFile.SetTo(new(std::nothrow) BFile(fileName, B_READ_WRITE)); + if (fFile.Get() == NULL) return; BPrivate::Storage::OffsetFile* offsetFile - = new(std::nothrow) BPrivate::Storage::OffsetFile(fFile, offset); + = new(std::nothrow) BPrivate::Storage::OffsetFile(fFile.Get(), offset); if (offsetFile == NULL || offsetFile->InitCheck() != B_OK) { delete offsetFile; return; } - fData = offsetFile; + fData.SetTo(offsetFile); - PictureDataWriter::SetTo(fData); + PictureDataWriter::SetTo(fData.Get()); } @@ -1151,24 +1140,18 @@ ServerPicture::~ServerPicture() { ASSERT(fOwner == NULL); - delete fData; - delete fFile; gTokenSpace.RemoveToken(fToken); - if (fPictures != NULL) { + if (fPictures.Get() != NULL) { for (int32 i = fPictures->CountItems(); i-- > 0;) { ServerPicture* picture = fPictures->ItemAt(i); picture->SetOwner(NULL); picture->ReleaseReference(); } - - delete fPictures; } - if (fPushed != NULL) { + if (fPushed != NULL) fPushed->SetOwner(NULL); - fPushed->ReleaseReference(); - } } @@ -1288,12 +1271,12 @@ ServerPicture::Play(Canvas* target) { // TODO: for now: then change PicturePlayer // to accept a BPositionIO object - BMallocIO* mallocIO = dynamic_cast(fData); + BMallocIO* mallocIO = dynamic_cast(fData.Get()); if (mallocIO == NULL) return; BPrivate::PicturePlayer player(mallocIO->Buffer(), - mallocIO->BufferLength(), PictureList::Private(fPictures).AsBList()); + mallocIO->BufferLength(), PictureList::Private(fPictures.Get()).AsBList()); player.Play(kPicturePlayerCallbacks, sizeof(kPicturePlayerCallbacks), target); } @@ -1307,8 +1290,7 @@ ServerPicture::PushPicture(ServerPicture* picture) if (fPushed != NULL) debugger("already pushed a picture"); - fPushed = picture; - fPushed->AcquireReference(); + fPushed.SetTo(picture, false); } @@ -1317,9 +1299,7 @@ ServerPicture::PushPicture(ServerPicture* picture) ServerPicture* ServerPicture::PopPicture() { - ServerPicture* old = fPushed; - fPushed = NULL; - return old; + return fPushed.Detach(); } @@ -1334,10 +1314,10 @@ ServerPicture::AppendPicture(ServerPicture* picture) bool ServerPicture::NestPicture(ServerPicture* picture) { - if (fPictures == NULL) - fPictures = new(std::nothrow) PictureList; + if (fPictures.Get() == NULL) + fPictures.SetTo(new(std::nothrow) PictureList); - if (fPictures == NULL || !fPictures->AddItem(picture)) + if (fPictures.Get() == NULL || !fPictures->AddItem(picture)) return false; picture->AcquireReference(); @@ -1348,7 +1328,7 @@ ServerPicture::NestPicture(ServerPicture* picture) off_t ServerPicture::DataLength() const { - if (fData == NULL) + if (fData.Get() == NULL) return 0; off_t size; fData->GetSize(&size); @@ -1389,7 +1369,7 @@ ServerPicture::ExportData(BPrivate::PortLink& link) fData->Seek(0, SEEK_SET); int32 subPicturesCount = 0; - if (fPictures != NULL) + if (fPictures.Get() != NULL) subPicturesCount = fPictures->CountItems(); link.Attach(subPicturesCount); if (subPicturesCount > 0) { diff --git a/src/servers/app/ServerPicture.h b/src/servers/app/ServerPicture.h index a8f8334a91..e6fcbc0eb8 100644 --- a/src/servers/app/ServerPicture.h +++ b/src/servers/app/ServerPicture.h @@ -14,6 +14,7 @@ #include +#include #include #include #include @@ -72,10 +73,14 @@ private: typedef BObjectList PictureList; int32 fToken; - BFile* fFile; - BPositionIO* fData; - PictureList* fPictures; - ServerPicture* fPushed; + ObjectDeleter + fFile; + ObjectDeleter + fData; + ObjectDeleter + fPictures; + BReference + fPushed; ServerApp* fOwner; }; diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index c23e3cfb42..cdc7a88813 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -2021,7 +2021,7 @@ fDesktop->LockSingleWindow(); rgb_color colorKey = {0}; if (status == B_OK) { - ServerBitmap* bitmap = fServerApp->GetBitmap(bitmapToken); + BReference bitmap(fServerApp->GetBitmap(bitmapToken), true); if (bitmapToken == -1 || bitmap != NULL) { bool wasOverlay = fCurrentView->ViewBitmap() != NULL && fCurrentView->ViewBitmap()->Overlay() != NULL; @@ -2045,9 +2045,6 @@ fDesktop->LockSingleWindow(); bitmap->Overlay()->SetFlags(options); colorKey = bitmap->Overlay()->Color(); } - - if (bitmap != NULL) - bitmap->ReleaseReference(); } else status = B_BAD_VALUE; } @@ -2093,20 +2090,16 @@ fDesktop->LockSingleWindow(); if (link.Read(&inverse) != B_OK) break; - ServerPicture* picture = fServerApp->GetPicture(pictureToken); + BReference picture(fServerApp->GetPicture(pictureToken), true); if (picture == NULL) break; - AlphaMask* const mask = new(std::nothrow) PictureAlphaMask( + BReference const mask(new(std::nothrow) PictureAlphaMask( fCurrentView->GetAlphaMask(), picture, - *fCurrentView->CurrentState(), where, inverse); + *fCurrentView->CurrentState(), where, inverse), true); fCurrentView->SetAlphaMask(mask); - if (mask != NULL) - mask->ReleaseReference(); _UpdateDrawState(fCurrentView); - - picture->ReleaseReference(); break; } @@ -2306,15 +2299,13 @@ fDesktop->LockSingleWindow(); BMessage dragMessage; if (link.Read(buffer, bufferSize) == B_OK && dragMessage.Unflatten(buffer) == B_OK) { - ServerBitmap* bitmap - = fServerApp->GetBitmap(bitmapToken); + BReference bitmap( + fServerApp->GetBitmap(bitmapToken), true); // TODO: possible deadlock fDesktop->UnlockSingleWindow(); fDesktop->EventDispatcher().SetDragMessage(dragMessage, bitmap, offset); fDesktop->LockSingleWindow(); - if (bitmap != NULL) - bitmap->ReleaseReference(); } delete[] buffer; } @@ -2380,7 +2371,7 @@ fDesktop->LockSingleWindow(); { DTRACE(("ServerWindow %s: Message AS_VIEW_BEGIN_PICTURE\n", Title())); - ServerPicture* picture = App()->CreatePicture(); + BReference picture(App()->CreatePicture(), true); if (picture != NULL) { picture->SyncState(fCurrentView); fCurrentView->SetPicture(picture); @@ -2396,14 +2387,12 @@ fDesktop->LockSingleWindow(); int32 token; link.Read(&token); - ServerPicture* picture = App()->GetPicture(token); + BReference picture(App()->GetPicture(token), true); if (picture != NULL) picture->SyncState(fCurrentView); fCurrentView->SetPicture(picture); - if (picture != NULL) - picture->ReleaseReference(); break; } @@ -2630,7 +2619,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, info.options |= B_FILTER_BITMAP_BILINEAR; #endif - ServerBitmap* bitmap = fServerApp->GetBitmap(info.bitmapToken); + BReference bitmap(fServerApp->GetBitmap(info.bitmapToken), true); if (bitmap != NULL) { DTRACE(("ServerWindow %s: Message AS_VIEW_DRAW_BITMAP: " "View: %s, bitmap: %" B_PRId32 " (size %" B_PRId32 " x " @@ -2651,8 +2640,6 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, drawingEngine->DrawBitmap(bitmap, info.bitmapRect, info.viewRect, info.options); - - bitmap->ReleaseReference(); } break; } @@ -3162,7 +3149,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPoint where; if (link.Read(&where) == B_OK) { - ServerPicture* picture = App()->GetPicture(token); + BReference picture(App()->GetPicture(token), true); if (picture != NULL) { // Setting the drawing origin outside of the // state makes sure that everything the picture @@ -3175,8 +3162,6 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, fCurrentView->PopState(); fCurrentView->PopState(); - - picture->ReleaseReference(); } } break; @@ -3902,7 +3887,7 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver& link) ViewDrawBitmapInfo info; link.Read(&info); - ServerBitmap* bitmap = App()->GetBitmap(info.bitmapToken); + BReference bitmap(App()->GetBitmap(info.bitmapToken), true); if (bitmap == NULL) break; @@ -3911,7 +3896,6 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver& link) bitmap->ColorSpace(), info.options, bitmap->Bits(), bitmap->BitsLength()); - bitmap->ReleaseReference(); break; } @@ -3922,15 +3906,13 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver& link) BPoint where; if (link.Read(&where) == B_OK) { - ServerPicture* pictureToDraw = App()->GetPicture(token); + BReference pictureToDraw(App()->GetPicture(token), true); if (pictureToDraw != NULL) { // We need to make a copy of the picture, since it can // change after it has been drawn - ServerPicture* copy = App()->CreatePicture(pictureToDraw); + BReference copy(App()->CreatePicture(pictureToDraw), true); picture->NestPicture(copy); picture->WriteDrawPicture(where, copy->Token()); - - pictureToDraw->ReleaseReference(); } } break; @@ -3975,15 +3957,13 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver& link) if (link.Read(&inverse) != B_OK) break; - ServerPicture* pictureToClip = fServerApp->GetPicture(pictureToken); + BReference pictureToClip(fServerApp->GetPicture(pictureToken), true); if (pictureToClip != NULL) { // We need to make a copy of the picture, since it can // change after it has been drawn - ServerPicture* copy = App()->CreatePicture(pictureToClip); + BReference copy(App()->CreatePicture(pictureToClip), true); picture->NestPicture(copy); picture->WriteClipToPicture(copy->Token(), where, inverse); - - pictureToClip->ReleaseReference(); } break; } @@ -4024,7 +4004,7 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver& link) case AS_VIEW_BEGIN_PICTURE: { - ServerPicture* newPicture = App()->CreatePicture(); + BReference newPicture(App()->CreatePicture(), true); if (newPicture != NULL) { newPicture->PushPicture(picture); newPicture->SyncState(fCurrentView); @@ -4038,7 +4018,7 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver& link) int32 token; link.Read(&token); - ServerPicture* appendPicture = App()->GetPicture(token); + BReference appendPicture(App()->GetPicture(token), true); if (appendPicture != NULL) { //picture->SyncState(fCurrentView); appendPicture->AppendPicture(picture); @@ -4046,17 +4026,13 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver& link) fCurrentView->SetPicture(appendPicture); - if (appendPicture != NULL) - appendPicture->ReleaseReference(); break; } case AS_VIEW_END_PICTURE: { - ServerPicture* poppedPicture = picture->PopPicture(); + BReference poppedPicture(picture->PopPicture(), true); fCurrentView->SetPicture(poppedPicture); - if (poppedPicture != NULL) - poppedPicture->ReleaseReference(); fLink.StartMessage(B_OK); fLink.Attach(picture->Token()); @@ -4095,7 +4071,7 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver& link) if (layer == NULL) break; - Layer* previousLayer = layer->PopLayer(); + BReference previousLayer(layer->PopLayer(), true); if (previousLayer == NULL) { // End last layer return false; diff --git a/src/servers/app/View.cpp b/src/servers/app/View.cpp index 4a276c7e9f..0e3b561616 100644 --- a/src/servers/app/View.cpp +++ b/src/servers/app/View.cpp @@ -126,26 +126,13 @@ View::View(IntRect frame, IntPoint scrollingOffset, const char* name, fUserClipping(NULL), fScreenAndUserClipping(NULL) { - if (fDrawState) + if (fDrawState.Get() != NULL) fDrawState->SetSubPixelPrecise(fFlags & B_SUBPIXEL_PRECISE); } View::~View() { - if (fViewBitmap != NULL) - fViewBitmap->ReleaseReference(); - - delete fScreenAndUserClipping; - delete fUserClipping; - delete fDrawState; - -// if (fWindow && this == fWindow->TopView()) -// fWindow->SetTopView(NULL); - - if (fCursor) - fCursor->ReleaseReference(); - // iterate over children and delete each one View* view = fFirstChild; while (view) { @@ -517,15 +504,9 @@ View::SetViewBitmap(ServerBitmap* bitmap, IntRect sourceRect, newOverlay->TakeOverToken(overlay); } else if (overlay != NULL) overlay->Hide(); - - fViewBitmap->ReleaseReference(); } - // the caller is allowed to delete the bitmap after setting the background - if (bitmap != NULL) - bitmap->AcquireReference(); - - fViewBitmap = bitmap; + fViewBitmap.SetTo(bitmap, false); fBitmapSource = sourceRect; fBitmapDestination = destRect; fBitmapResizingMode = resizingMode; @@ -985,15 +966,17 @@ View::ViewUIColor(float* tint) void View::PushState() { - DrawState* newState = fDrawState->PushState(); - if (newState) { - fDrawState = newState; - // In BeAPI, B_SUBPIXEL_PRECISE is a view flag, and not affected by the - // view state. Our implementation moves it to the draw state, but let's - // be compatible with the API here and make it survive accross state - // changes. - fDrawState->SetSubPixelPrecise(fFlags & B_SUBPIXEL_PRECISE); - } + DrawState* previousState = fDrawState.Detach(); + DrawState* newState = previousState->PushState(); + if (newState == NULL) + newState = previousState; + + fDrawState.SetTo(newState); + // In BeAPI, B_SUBPIXEL_PRECISE is a view flag, and not affected by the + // view state. Our implementation moves it to the draw state, but let's + // be compatible with the API here and make it survive accross state + // changes. + fDrawState->SetSubPixelPrecise(fFlags & B_SUBPIXEL_PRECISE); } @@ -1008,7 +991,7 @@ View::PopState() bool rebuildClipping = fDrawState->HasAdditionalClipping(); - fDrawState = fDrawState->PopState(); + fDrawState.SetTo(fDrawState->PopState()); fDrawState->SetSubPixelPrecise(fFlags & B_SUBPIXEL_PRECISE); // rebuild clipping @@ -1035,13 +1018,7 @@ View::SetCursor(ServerCursor* cursor) if (cursor == fCursor) return; - if (fCursor) - fCursor->ReleaseReference(); - - fCursor = cursor; - - if (fCursor) - fCursor->AcquireReference(); + fCursor.SetTo(cursor, false); } @@ -1051,13 +1028,7 @@ View::SetPicture(ServerPicture* picture) if (picture == fPicture) return; - if (fPicture != NULL) - fPicture->ReleaseReference(); - - fPicture = picture; - - if (fPicture != NULL) - fPicture->AcquireReference(); + fPicture.SetTo(picture, false); } @@ -1066,7 +1037,7 @@ View::BlendAllLayers() { if (fPicture == NULL) return; - Layer* layer = dynamic_cast(fPicture); + Layer* layer = dynamic_cast(fPicture.Get()); if (layer == NULL) return; BlendLayer(layer); @@ -1378,13 +1349,13 @@ View::PrintToStream() const printf(" valid: %d\n", fScreenClippingValid); printf(" fUserClipping:\n"); - if (fUserClipping != NULL) + if (fUserClipping.Get() != NULL) fUserClipping->PrintToStream(); else printf(" none\n"); printf(" fScreenAndUserClipping:\n"); - if (fScreenAndUserClipping != NULL) + if (fScreenAndUserClipping.Get() != NULL) fScreenAndUserClipping->PrintToStream(); else printf(" invalid\n"); @@ -1438,20 +1409,18 @@ View::RebuildClipping(bool deep) // hand, views for which this feature is actually used will // probably not have any children, so it is not that expensive // after all - if (fUserClipping == NULL) { - fUserClipping = new (nothrow) BRegion; - if (fUserClipping == NULL) + if (fUserClipping.Get() == NULL) { + fUserClipping.SetTo(new (nothrow) BRegion); + if (fUserClipping.Get() == NULL) return; } - fDrawState->GetCombinedClippingRegion(fUserClipping); + fDrawState->GetCombinedClippingRegion(fUserClipping.Get()); } else { - delete fUserClipping; - fUserClipping = NULL; + fUserClipping.SetTo(NULL); } - delete fScreenAndUserClipping; - fScreenAndUserClipping = NULL; + fScreenAndUserClipping.SetTo(NULL); fScreenClippingValid = false; } @@ -1460,22 +1429,22 @@ BRegion& View::ScreenAndUserClipping(BRegion* windowContentClipping, bool force) const { // no user clipping - return screen clipping directly - if (fUserClipping == NULL) + if (fUserClipping.Get() == NULL) return _ScreenClipping(windowContentClipping, force); // combined screen and user clipping already valid - if (fScreenAndUserClipping != NULL) - return *fScreenAndUserClipping; + if (fScreenAndUserClipping.Get() != NULL) + return *fScreenAndUserClipping.Get(); // build a new combined user and screen clipping - fScreenAndUserClipping = new (nothrow) BRegion(*fUserClipping); - if (fScreenAndUserClipping == NULL) + fScreenAndUserClipping.SetTo(new (nothrow) BRegion(*fUserClipping.Get())); + if (fScreenAndUserClipping.Get() == NULL) return fScreenClipping; - LocalToScreenTransform().Apply(fScreenAndUserClipping); + LocalToScreenTransform().Apply(fScreenAndUserClipping.Get()); fScreenAndUserClipping->IntersectWith( &_ScreenClipping(windowContentClipping, force)); - return *fScreenAndUserClipping; + return *fScreenAndUserClipping.Get(); } @@ -1498,8 +1467,7 @@ View::InvalidateScreenClipping() // if (!fScreenClippingValid) // return; - delete fScreenAndUserClipping; - fScreenAndUserClipping = NULL; + fScreenAndUserClipping.SetTo(NULL); fScreenClippingValid = false; // invalidate the childrens screen clipping as well for (View* child = FirstChild(); child; child = child->NextSibling()) { @@ -1539,8 +1507,7 @@ View::_MoveScreenClipping(int32 x, int32 y, bool deep) { if (fScreenClippingValid) { fScreenClipping.OffsetBy(x, y); - delete fScreenAndUserClipping; - fScreenAndUserClipping = NULL; + fScreenAndUserClipping.SetTo(NULL); } if (deep) { diff --git a/src/servers/app/View.h b/src/servers/app/View.h index 84e2b3cf16..d5a7ee2f7e 100644 --- a/src/servers/app/View.h +++ b/src/servers/app/View.h @@ -19,10 +19,12 @@ #include "Canvas.h" #include "IntRect.h" +#include #include #include #include #include +#include #include class BList; @@ -208,9 +210,9 @@ public: inline bool IsScreenClippingValid() const { return fScreenClippingValid - && (fUserClipping == NULL - || (fUserClipping != NULL - && fScreenAndUserClipping != NULL)); + && (fUserClipping.Get() == NULL + || (fUserClipping.Get() != NULL + && fScreenAndUserClipping.Get() != NULL)); } // debugging @@ -243,7 +245,8 @@ protected: rgb_color fViewColor; color_which fWhichViewColor; float fWhichViewColorTint; - ServerBitmap* fViewBitmap; + BReference + fViewBitmap; IntRect fBitmapSource; IntRect fBitmapDestination; int32 fBitmapResizingMode; @@ -267,8 +270,10 @@ protected: View* fNextSibling; View* fLastChild; - ServerCursor* fCursor; - ServerPicture* fPicture; + BReference + fCursor; + BReference + fPicture; // clipping BRegion fLocalClipping; @@ -276,8 +281,10 @@ protected: mutable BRegion fScreenClipping; mutable bool fScreenClippingValid; - BRegion* fUserClipping; - mutable BRegion* fScreenAndUserClipping; + ObjectDeleter + fUserClipping; + mutable ObjectDeleter + fScreenAndUserClipping; }; #endif // VIEW_H diff --git a/src/servers/app/drawing/AlphaMask.cpp b/src/servers/app/drawing/AlphaMask.cpp index 21d15df5ff..d6c128f85a 100644 --- a/src/servers/app/drawing/AlphaMask.cpp +++ b/src/servers/app/drawing/AlphaMask.cpp @@ -338,13 +338,13 @@ VectorAlphaMask::_RenderSource(const IntRect& canvasBounds) // Render the picture to the bitmap BitmapHWInterface interface(bitmap); - DrawingEngine* engine = interface.CreateDrawingEngine(); - if (engine == NULL) + ObjectDeleter engine(interface.CreateDrawingEngine()); + if (engine.Get() == NULL) return NULL; engine->SetRendererOffset(fBounds.left, fBounds.top); - OffscreenCanvas canvas(engine, + OffscreenCanvas canvas(engine.Get(), static_cast(this)->GetDrawState(), fBounds); DrawState* const drawState = canvas.CurrentState(); @@ -364,7 +364,6 @@ VectorAlphaMask::_RenderSource(const IntRect& canvasBounds) } canvas.PopState(); - delete engine; return bitmap.Detach(); } diff --git a/src/servers/app/drawing/BitmapDrawingEngine.cpp b/src/servers/app/drawing/BitmapDrawingEngine.cpp index 7a9e0ef504..bf652efd0e 100644 --- a/src/servers/app/drawing/BitmapDrawingEngine.cpp +++ b/src/servers/app/drawing/BitmapDrawingEngine.cpp @@ -48,29 +48,23 @@ BitmapDrawingEngine::SetSize(int32 newWidth, int32 newHeight) } SetHWInterface(NULL); - if (fHWInterface != NULL) { + if (fHWInterface.Get() != NULL) { fHWInterface->LockExclusiveAccess(); fHWInterface->Shutdown(); fHWInterface->UnlockExclusiveAccess(); - delete fHWInterface; - fHWInterface = NULL; - } - - if (fBitmap != NULL) { - fBitmap->ReleaseReference(); - fBitmap = NULL; + fHWInterface.Unset(); } if (newWidth <= 0 || newHeight <= 0) return B_OK; - fBitmap = new(std::nothrow) UtilityBitmap(BRect(0, 0, newWidth - 1, - newHeight - 1), fColorSpace, 0); - if (fBitmap == NULL) + fBitmap.SetTo(new(std::nothrow) UtilityBitmap(BRect(0, 0, newWidth - 1, + newHeight - 1), fColorSpace, 0)); + if (fBitmap.Get() == NULL) return B_NO_MEMORY; - fHWInterface = new(std::nothrow) BitmapHWInterface(fBitmap); - if (fHWInterface == NULL) + fHWInterface.SetTo(new(std::nothrow) BitmapHWInterface(fBitmap)); + if (fHWInterface.Get() == NULL) return B_NO_MEMORY; status_t result = fHWInterface->Initialize(); @@ -80,7 +74,7 @@ BitmapDrawingEngine::SetSize(int32 newWidth, int32 newHeight) // we have to set a valid clipping first fClipping.Set(fBitmap->Bounds()); ConstrainClippingRegion(&fClipping); - SetHWInterface(fHWInterface); + SetHWInterface(fHWInterface.Get()); return B_OK; } diff --git a/src/servers/app/drawing/BitmapDrawingEngine.h b/src/servers/app/drawing/BitmapDrawingEngine.h index 11e5b814bd..32343893f6 100644 --- a/src/servers/app/drawing/BitmapDrawingEngine.h +++ b/src/servers/app/drawing/BitmapDrawingEngine.h @@ -2,6 +2,9 @@ #define BITMAP_DRAWING_ENGINE_H #include "DrawingEngine.h" + +#include +#include #include class BitmapHWInterface; @@ -24,8 +27,10 @@ virtual ~BitmapDrawingEngine(); private: color_space fColorSpace; - BitmapHWInterface* fHWInterface; - UtilityBitmap* fBitmap; + ObjectDeleter + fHWInterface; + BReference + fBitmap; BRegion fClipping; }; diff --git a/src/servers/app/drawing/HWInterface.cpp b/src/servers/app/drawing/HWInterface.cpp index e98bc51deb..c449f13810 100644 --- a/src/servers/app/drawing/HWInterface.cpp +++ b/src/servers/app/drawing/HWInterface.cpp @@ -43,7 +43,6 @@ HWInterfaceListener::~HWInterfaceListener() HWInterface::HWInterface(bool doubleBuffered, bool enableUpdateQueue) : MultiLocker("hw interface lock"), - fCursorAreaBackup(NULL), fFloatingOverlaysLock("floating overlays lock"), fCursor(NULL), fDragBitmap(NULL), @@ -65,12 +64,6 @@ HWInterface::HWInterface(bool doubleBuffered, bool enableUpdateQueue) HWInterface::~HWInterface() { SetAsyncDoubleBuffered(false); - - delete fCursorAreaBackup; - - // The standard cursor doesn't belong us - the drag bitmap might - if (fCursor != fCursorAndDragBitmap) - delete fCursorAndDragBitmap; } @@ -132,25 +125,14 @@ HWInterface::SetCursor(ServerCursor* cursor) if (!fFloatingOverlaysLock.Lock()) return; - if (fCursor != cursor) { + if (fCursor.Get() != cursor) { BRect oldFrame = _CursorFrame(); - if (fCursorAndDragBitmap == fCursor) { - // make sure _AdoptDragBitmap doesn't delete a real cursor - fCursorAndDragBitmap = NULL; - } - - if (fCursor) - fCursor->ReleaseReference(); - - fCursor = cursor; - - if (fCursor) - fCursor->AcquireReference(); + fCursor.SetTo(cursor); Invalidate(oldFrame); - _AdoptDragBitmap(fDragBitmap, fDragBitmapOffset); + _AdoptDragBitmap(); Invalidate(_CursorFrame()); } fFloatingOverlaysLock.Unlock(); @@ -163,9 +145,8 @@ HWInterface::Cursor() const if (!fFloatingOverlaysLock.Lock()) return ServerCursorReference(NULL); - ServerCursorReference reference(fCursor); fFloatingOverlaysLock.Unlock(); - return reference; + return fCursor; } @@ -175,9 +156,8 @@ HWInterface::CursorAndDragBitmap() const if (!fFloatingOverlaysLock.Lock()) return ServerCursorReference(NULL); - ServerCursorReference reference(fCursorAndDragBitmap); fFloatingOverlaysLock.Unlock(); - return reference; + return fCursorAndDragBitmap; } @@ -255,7 +235,7 @@ HWInterface::MoveCursorTo(float x, float y) // anything if the cursor is hidden // (invalid cursor frame), but explicitly // testing for it here saves us some cycles - if (fCursorAreaBackup) { + if (fCursorAreaBackup.Get() != NULL) { // means we have a software cursor which we need to draw _RestoreCursorArea(); _DrawCursor(_CursorFrame()); @@ -290,7 +270,9 @@ HWInterface::SetDragBitmap(const ServerBitmap* bitmap, const BPoint& offsetFromCursor) { if (fFloatingOverlaysLock.Lock()) { - _AdoptDragBitmap(bitmap, offsetFromCursor); + fDragBitmap.SetTo((ServerBitmap*)bitmap, false); + fDragBitmapOffset = offsetFromCursor; + _AdoptDragBitmap(); fFloatingOverlaysLock.Unlock(); } } @@ -312,16 +294,15 @@ void HWInterface::SetAsyncDoubleBuffered(bool doubleBuffered) { if (doubleBuffered) { - if (fUpdateExecutor != NULL) + if (fUpdateExecutor.Get() != NULL) return; - fUpdateExecutor = new (nothrow) UpdateQueue(this); - AddListener(fUpdateExecutor); + fUpdateExecutor.SetTo(new (nothrow) UpdateQueue(this)); + AddListener(fUpdateExecutor.Get()); } else { - if (fUpdateExecutor == NULL) + if (fUpdateExecutor.Get() == NULL) return; - RemoveListener(fUpdateExecutor); - delete fUpdateExecutor; - fUpdateExecutor = NULL; + RemoveListener(fUpdateExecutor.Get()); + fUpdateExecutor.Unset(); } } @@ -499,7 +480,7 @@ HWInterface::HideFloatingOverlays(const BRect& area) return false; if (!fFloatingOverlaysLock.Lock()) return false; - if (fCursorAreaBackup && !fCursorAreaBackup->cursor_hidden) { + if (fCursorAreaBackup.Get() != NULL && !fCursorAreaBackup->cursor_hidden) { BRect backupArea(fCursorAreaBackup->left, fCursorAreaBackup->top, fCursorAreaBackup->right, fCursorAreaBackup->bottom); if (area.Intersects(backupArea)) { @@ -529,7 +510,7 @@ HWInterface::HideFloatingOverlays() void HWInterface::ShowFloatingOverlays() { - if (fCursorAreaBackup && fCursorAreaBackup->cursor_hidden) + if (fCursorAreaBackup.Get() != NULL && fCursorAreaBackup->cursor_hidden) _DrawCursor(_CursorFrame()); fFloatingOverlaysLock.Unlock(); @@ -607,7 +588,7 @@ HWInterface::_DrawCursor(IntRect area) const uint8* dst = buffer; - if (fCursorAreaBackup && fCursorAreaBackup->buffer + if (fCursorAreaBackup.Get() != NULL && fCursorAreaBackup->buffer && fFloatingOverlaysLock.Lock()) { fCursorAreaBackup->cursor_hidden = false; // remember which area the backup contains @@ -904,7 +885,7 @@ HWInterface::_CursorFrame() const void HWInterface::_RestoreCursorArea() const { - if (fCursorAreaBackup && !fCursorAreaBackup->cursor_hidden) { + if (fCursorAreaBackup.Get() != NULL && !fCursorAreaBackup->cursor_hidden) { _CopyToFront(fCursorAreaBackup->buffer, fCursorAreaBackup->bpr, fCursorAreaBackup->left, fCursorAreaBackup->top, fCursorAreaBackup->right, fCursorAreaBackup->bottom); @@ -915,11 +896,11 @@ HWInterface::_RestoreCursorArea() const void -HWInterface::_AdoptDragBitmap(const ServerBitmap* bitmap, const BPoint& offset) +HWInterface::_AdoptDragBitmap() { // TODO: support other colorspaces/convert bitmap - if (bitmap && !(bitmap->ColorSpace() == B_RGB32 - || bitmap->ColorSpace() == B_RGBA32)) { + if (fDragBitmap && !(fDragBitmap->ColorSpace() == B_RGB32 + || fDragBitmap->ColorSpace() == B_RGBA32)) { fprintf(stderr, "HWInterface::_AdoptDragBitmap() - bitmap has yet " "unsupported colorspace\n"); return; @@ -928,17 +909,12 @@ HWInterface::_AdoptDragBitmap(const ServerBitmap* bitmap, const BPoint& offset) _RestoreCursorArea(); BRect oldCursorFrame = _CursorFrame(); - if (fCursorAndDragBitmap && fCursorAndDragBitmap != fCursor) { - delete fCursorAndDragBitmap; - fCursorAndDragBitmap = NULL; - } - - if (bitmap != NULL && bitmap->Bounds().Width() > 0 && bitmap->Bounds().Height() > 0) { - BRect bitmapFrame = bitmap->Bounds(); + if (fDragBitmap != NULL && fDragBitmap->Bounds().Width() > 0 && fDragBitmap->Bounds().Height() > 0) { + BRect bitmapFrame = fDragBitmap->Bounds(); if (fCursor) { // put bitmap frame and cursor frame into the same // coordinate space (the cursor location is the origin) - bitmapFrame.OffsetTo(BPoint(-offset.x, -offset.y)); + bitmapFrame.OffsetTo(BPoint(-fDragBitmapOffset.x, -fDragBitmapOffset.y)); BRect cursorFrame(fCursor->Bounds()); BPoint hotspot(fCursor->GetHotSpot()); @@ -955,14 +931,13 @@ HWInterface::_AdoptDragBitmap(const ServerBitmap* bitmap, const BPoint& offset) cursorFrame.OffsetBy(shift); bitmapFrame.OffsetBy(shift); - fCursorAndDragBitmap = new(std::nothrow) ServerCursor(combindedBounds, - bitmap->ColorSpace(), 0, shift); + fCursorAndDragBitmap.SetTo(new(std::nothrow) ServerCursor(combindedBounds, + fDragBitmap->ColorSpace(), 0, shift), true); uint8* dst = fCursorAndDragBitmap ? (uint8*)fCursorAndDragBitmap->Bits() : NULL; if (dst == NULL) { // Oops, we could not allocate memory for the drag bitmap. // Let's show the cursor only. - delete fCursorAndDragBitmap; fCursorAndDragBitmap = fCursor; } else { // clear the combined buffer @@ -971,8 +946,8 @@ HWInterface::_AdoptDragBitmap(const ServerBitmap* bitmap, const BPoint& offset) memset(dst, 0, fCursorAndDragBitmap->BitsLength()); // put drag bitmap into combined buffer - uint8* src = (uint8*)bitmap->Bits(); - uint32 srcBPR = bitmap->BytesPerRow(); + uint8* src = (uint8*)fDragBitmap->Bits(); + uint32 srcBPR = fDragBitmap->BytesPerRow(); dst += (int32)bitmapFrame.top * dstBPR + (int32)bitmapFrame.left * 4; @@ -1055,10 +1030,10 @@ HWInterface::_AdoptDragBitmap(const ServerBitmap* bitmap, const BPoint& offset) } } } else { - fCursorAndDragBitmap = new ServerCursor(bitmap->Bits(), + fCursorAndDragBitmap.SetTo(new ServerCursor(fDragBitmap->Bits(), bitmapFrame.IntegerWidth() + 1, bitmapFrame.IntegerHeight() + 1, - bitmap->ColorSpace()); - fCursorAndDragBitmap->SetHotSpot(BPoint(-offset.x, -offset.y)); + fDragBitmap->ColorSpace()), true); + fCursorAndDragBitmap->SetHotSpot(BPoint(-fDragBitmapOffset.x, -fDragBitmapOffset.y)); } } else { fCursorAndDragBitmap = fCursor; @@ -1066,31 +1041,17 @@ HWInterface::_AdoptDragBitmap(const ServerBitmap* bitmap, const BPoint& offset) Invalidate(oldCursorFrame); -// NOTE: the EventDispatcher does the reference counting stuff for us -// TODO: You can not simply call Release() on a ServerBitmap like you -// can for a ServerCursor... it could be changed, but there are linking -// troubles with the test environment that need to be solved than. -// if (fDragBitmap) -// fDragBitmap->Release(); - fDragBitmap = bitmap; - fDragBitmapOffset = offset; -// if (fDragBitmap) -// fDragBitmap->Acquire(); - - delete fCursorAreaBackup; - fCursorAreaBackup = NULL; + fCursorAreaBackup.Unset(); if (!fCursorAndDragBitmap) return; if (fCursorAndDragBitmap && !IsDoubleBuffered()) { BRect cursorBounds = fCursorAndDragBitmap->Bounds(); - fCursorAreaBackup = new buffer_clip(cursorBounds.IntegerWidth() + 1, - cursorBounds.IntegerHeight() + 1); - if (fCursorAreaBackup->buffer == NULL) { - delete fCursorAreaBackup; - fCursorAreaBackup = NULL; - } + fCursorAreaBackup.SetTo(new buffer_clip(cursorBounds.IntegerWidth() + 1, + cursorBounds.IntegerHeight() + 1)); + if (fCursorAreaBackup->buffer == NULL) + fCursorAreaBackup.Unset(); } _DrawCursor(_CursorFrame()); } diff --git a/src/servers/app/drawing/HWInterface.h b/src/servers/app/drawing/HWInterface.h index 11242f06c4..a656ac089f 100644 --- a/src/servers/app/drawing/HWInterface.h +++ b/src/servers/app/drawing/HWInterface.h @@ -9,6 +9,7 @@ #define HW_INTERFACE_H +#include #include #include #include @@ -209,8 +210,7 @@ protected: IntRect _CursorFrame() const; void _RestoreCursorArea() const; - void _AdoptDragBitmap(const ServerBitmap* bitmap, - const BPoint& offset); + void _AdoptDragBitmap(); void _NotifyFrameBufferChanged(); void _NotifyScreenChanged(); @@ -250,13 +250,17 @@ protected: bool cursor_hidden; }; - buffer_clip* fCursorAreaBackup; + ObjectDeleter + fCursorAreaBackup; mutable BLocker fFloatingOverlaysLock; - ServerCursor* fCursor; - const ServerBitmap* fDragBitmap; + ServerCursorReference + fCursor; + BReference + fDragBitmap; BPoint fDragBitmapOffset; - ServerCursor* fCursorAndDragBitmap; + ServerCursorReference + fCursorAndDragBitmap; bool fCursorVisible; bool fCursorObscured; bool fHardwareCursorEnabled; @@ -268,7 +272,8 @@ protected: int fVGADevice; private: - UpdateQueue* fUpdateExecutor; + ObjectDeleter + fUpdateExecutor; BList fListeners; }; diff --git a/src/servers/app/font/FontCache.cpp b/src/servers/app/font/FontCache.cpp index ad33289b91..f27e208f7b 100644 --- a/src/servers/app/font/FontCache.cpp +++ b/src/servers/app/font/FontCache.cpp @@ -36,9 +36,6 @@ FontCache::FontCache() // destructor FontCache::~FontCache() { - FontMap::Iterator iterator = fFontCacheEntries.GetIterator(); - while (iterator.HasNext()) - iterator.Next().value->ReleaseReference(); } // Default @@ -59,13 +56,12 @@ FontCache::FontCacheEntryFor(const ServerFont& font, bool forceVector) AutoReadLocker readLocker(this); - FontCacheEntry* entry = fFontCacheEntries.Get(signature); + BReference entry = fFontCacheEntries.Get(signature); if (entry) { // the entry was already there - entry->AcquireReference(); //printf("FontCacheEntryFor(%ld): %p\n", font.GetFamilyAndStyle(), entry); - return entry; + return entry.Detach(); } readLocker.Unlock(); @@ -85,19 +81,17 @@ FontCache::FontCacheEntryFor(const ServerFont& font, bool forceVector) if (!entry) { // remove old entries, keep entries below certain count _ConstrainEntryCount(); - entry = new (nothrow) FontCacheEntry(); + entry.SetTo(new (nothrow) FontCacheEntry(), true); if (!entry || !entry->Init(font, forceVector) || fFontCacheEntries.Put(signature, entry) < B_OK) { fprintf(stderr, "FontCache::FontCacheEntryFor() - " "out of memory or no font file\n"); - delete entry; return NULL; } } //printf("FontCacheEntryFor(%ld): %p (insert)\n", font.GetFamilyAndStyle(), entry); - entry->AcquireReference(); - return entry; + return entry.Detach(); } // Recycle @@ -153,9 +147,8 @@ FontCache::_ConstrainEntryCount() iterator = fFontCacheEntries.GetIterator(); while (iterator.HasNext()) { - if (iterator.Next().value == leastUsedEntry) { + if (iterator.Next().value.Get() == leastUsedEntry) { fFontCacheEntries.Remove(iterator); - leastUsedEntry->ReleaseReference(); break; } } diff --git a/src/servers/app/font/FontCache.h b/src/servers/app/font/FontCache.h index aaa0058697..361f1fa8cc 100644 --- a/src/servers/app/font/FontCache.h +++ b/src/servers/app/font/FontCache.h @@ -33,7 +33,7 @@ class FontCache : public MultiLocker { static FontCache sDefaultInstance; - typedef HashMap FontMap; + typedef HashMap > FontMap; FontMap fFontCacheEntries; }; diff --git a/src/servers/app/font/FontFamily.cpp b/src/servers/app/font/FontFamily.cpp index 3d1532e60a..32c5938b02 100644 --- a/src/servers/app/font/FontFamily.cpp +++ b/src/servers/app/font/FontFamily.cpp @@ -78,7 +78,6 @@ FontFamily::~FontFamily() // we remove us before deleting the style, so that the font manager // is not contacted to remove the style from us style->_SetFontFamily(NULL, -1); - delete style; } } diff --git a/src/servers/app/font/FontManager.cpp b/src/servers/app/font/FontManager.cpp index 5ae176dd33..b9e3130841 100644 --- a/src/servers/app/font/FontManager.cpp +++ b/src/servers/app/font/FontManager.cpp @@ -408,7 +408,7 @@ FontManager::_RemoveStyle(font_directory& directory, FontStyle* style) fStyleHashTable.Remove(FontKey(style->Family()->ID(), style->ID())); - style->Release(); + style->ReleaseReference(); } diff --git a/src/servers/app/font/FontManager.h b/src/servers/app/font/FontManager.h index 741f7a3fab..813f284447 100644 --- a/src/servers/app/font/FontManager.h +++ b/src/servers/app/font/FontManager.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include FT_FREETYPE_H @@ -140,7 +141,7 @@ private: MappingList fMappings; FamilyList fFamilies; - HashMap fStyleHashTable; + HashMap > fStyleHashTable; ServerFont* fDefaultPlainFont; ServerFont* fDefaultBoldFont; diff --git a/src/servers/app/font/FontStyle.h b/src/servers/app/font/FontStyle.h index 4635cec917..06b36932ae 100644 --- a/src/servers/app/font/FontStyle.h +++ b/src/servers/app/font/FontStyle.h @@ -16,11 +16,11 @@ #include #include #include +#include #include #include #include FT_FREETYPE_H -#include "ReferenceCounting.h" struct node_ref; @@ -35,7 +35,7 @@ class ServerFont; FontStyle objects help abstract a lot of the font engine details while still offering plenty of information the style in question. */ -class FontStyle : public ReferenceCounting { +class FontStyle : public BReferenceable { public: FontStyle(node_ref& nodeRef, const char* path, FT_Face face);