Make it possible to reconnect BBitmap to the app_server.
* maintain a list of all BBitmaps * refactor the client memory allocator class, its possible now to just clone existing client area
This commit is contained in:
parent
04209cdd81
commit
577f58763b
@ -110,10 +110,12 @@ public:
|
|||||||
|
|
||||||
BBitmap& operator=(const BBitmap& source);
|
BBitmap& operator=(const BBitmap& source);
|
||||||
|
|
||||||
|
class Private;
|
||||||
private:
|
private:
|
||||||
friend class BView;
|
friend class BView;
|
||||||
friend class BApplication;
|
friend class BApplication;
|
||||||
friend class BPrivate::BPrivateScreen;
|
friend class BPrivate::BPrivateScreen;
|
||||||
|
friend class Private;
|
||||||
|
|
||||||
virtual status_t Perform(perform_code d, void* arg);
|
virtual status_t Perform(perform_code d, void* arg);
|
||||||
virtual void _ReservedBitmap1();
|
virtual void _ReservedBitmap1();
|
||||||
@ -127,6 +129,8 @@ private:
|
|||||||
void _CleanUp();
|
void _CleanUp();
|
||||||
void _AssertPointer();
|
void _AssertPointer();
|
||||||
|
|
||||||
|
void _ReconnectToAppServer();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8* fBasePointer;
|
uint8* fBasePointer;
|
||||||
int32 fSize;
|
int32 fSize;
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#define _BITMAP_PRIVATE_H
|
#define _BITMAP_PRIVATE_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <Bitmap.h>
|
||||||
#include <OS.h>
|
#include <OS.h>
|
||||||
|
|
||||||
|
|
||||||
@ -16,4 +17,16 @@ struct overlay_client_data {
|
|||||||
uint8* buffer;
|
uint8* buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void reconnect_bitmaps_to_app_server();
|
||||||
|
|
||||||
|
|
||||||
|
class BBitmap::Private {
|
||||||
|
public:
|
||||||
|
Private(BBitmap* bitmap);
|
||||||
|
void ReconnectToAppServer();
|
||||||
|
private:
|
||||||
|
BBitmap* fBitmap;
|
||||||
|
};
|
||||||
|
|
||||||
#endif // _BITMAP_PRIVATE_H
|
#endif // _BITMAP_PRIVATE_H
|
||||||
|
@ -32,6 +32,8 @@
|
|||||||
|
|
||||||
#include <ApplicationPrivate.h>
|
#include <ApplicationPrivate.h>
|
||||||
#include <AppServerLink.h>
|
#include <AppServerLink.h>
|
||||||
|
#include <Autolock.h>
|
||||||
|
#include <ObjectList.h>
|
||||||
#include <ServerMemoryAllocator.h>
|
#include <ServerMemoryAllocator.h>
|
||||||
#include <ServerProtocol.h>
|
#include <ServerProtocol.h>
|
||||||
|
|
||||||
@ -42,6 +44,35 @@
|
|||||||
using namespace BPrivate;
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
|
||||||
|
static BObjectList<BBitmap> sBitmapList;
|
||||||
|
static BLocker sBitmapListLock;
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
reconnect_bitmaps_to_app_server()
|
||||||
|
{
|
||||||
|
BAutolock _(sBitmapListLock);
|
||||||
|
for (int32 i = 0; i < sBitmapList.CountItems(); i++) {
|
||||||
|
BBitmap::Private bitmap(sBitmapList.ItemAt(i));
|
||||||
|
bitmap.ReconnectToAppServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BBitmap::Private::Private(BBitmap* bitmap)
|
||||||
|
:
|
||||||
|
fBitmap(bitmap)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BBitmap::Private::ReconnectToAppServer()
|
||||||
|
{
|
||||||
|
fBitmap->_ReconnectToAppServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Returns the number of bytes per row needed to store the actual
|
/*! \brief Returns the number of bytes per row needed to store the actual
|
||||||
bitmap data (not including any padding) given a color space and a
|
bitmap data (not including any padding) given a color space and a
|
||||||
row width.
|
row width.
|
||||||
@ -1087,6 +1118,9 @@ BBitmap::_InitObject(BRect bounds, color_space colorSpace, uint32 flags,
|
|||||||
fAreaOffset = -1;
|
fAreaOffset = -1;
|
||||||
// NOTE: why not "0" in case of error?
|
// NOTE: why not "0" in case of error?
|
||||||
fFlags = flags;
|
fFlags = flags;
|
||||||
|
} else {
|
||||||
|
BAutolock _(sBitmapListLock);
|
||||||
|
sBitmapList.AddItem(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fWindow = NULL;
|
fWindow = NULL;
|
||||||
@ -1157,6 +1191,9 @@ BBitmap::_CleanUp()
|
|||||||
fArea = -1;
|
fArea = -1;
|
||||||
fServerToken = -1;
|
fServerToken = -1;
|
||||||
fAreaOffset = -1;
|
fAreaOffset = -1;
|
||||||
|
|
||||||
|
BAutolock _(sBitmapListLock);
|
||||||
|
sBitmapList.RemoveItem(this);
|
||||||
}
|
}
|
||||||
fBasePointer = NULL;
|
fBasePointer = NULL;
|
||||||
}
|
}
|
||||||
@ -1174,3 +1211,27 @@ BBitmap::_AssertPointer()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BBitmap::_ReconnectToAppServer()
|
||||||
|
{
|
||||||
|
BPrivate::AppServerLink link;
|
||||||
|
|
||||||
|
link.StartMessage(AS_RECONNECT_BITMAP);
|
||||||
|
link.Attach<BRect>(fBounds);
|
||||||
|
link.Attach<color_space>(fColorSpace);
|
||||||
|
link.Attach<uint32>(fFlags);
|
||||||
|
link.Attach<int32>(fBytesPerRow);
|
||||||
|
link.Attach<int32>(0);
|
||||||
|
link.Attach<int32>(fArea);
|
||||||
|
link.Attach<int32>(fAreaOffset);
|
||||||
|
|
||||||
|
status_t error;
|
||||||
|
if (link.FlushWithReply(error) == B_OK && error == B_OK) {
|
||||||
|
// server side success
|
||||||
|
// Get token
|
||||||
|
link.Read<int32>(&fServerToken);
|
||||||
|
|
||||||
|
link.Read<area_id>(&fServerArea);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -68,14 +68,8 @@ BitmapManager::BitmapManager()
|
|||||||
BitmapManager::~BitmapManager()
|
BitmapManager::~BitmapManager()
|
||||||
{
|
{
|
||||||
int32 count = fBitmapList.CountItems();
|
int32 count = fBitmapList.CountItems();
|
||||||
for (int32 i = 0; i < count; i++) {
|
for (int32 i = 0; i < count; i++)
|
||||||
if (ServerBitmap* bitmap = (ServerBitmap*)fBitmapList.ItemAt(i)) {
|
delete (ServerBitmap*)fBitmapList.ItemAt(i);
|
||||||
if (bitmap->AllocationCookie() != NULL)
|
|
||||||
debugger("We're not supposed to keep our cookies...");
|
|
||||||
|
|
||||||
delete bitmap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -94,7 +88,6 @@ BitmapManager::CreateBitmap(ClientMemoryAllocator* allocator,
|
|||||||
int32 bytesPerRow, int32 screen, uint8* _allocationFlags)
|
int32 bytesPerRow, int32 screen, uint8* _allocationFlags)
|
||||||
{
|
{
|
||||||
BAutolock locker(fLock);
|
BAutolock locker(fLock);
|
||||||
|
|
||||||
if (!locker.IsLocked())
|
if (!locker.IsLocked())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -112,7 +105,7 @@ BitmapManager::CreateBitmap(ClientMemoryAllocator* allocator,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerBitmap* bitmap = new(nothrow) ServerBitmap(bounds, space, flags,
|
ServerBitmap* bitmap = new(std::nothrow) ServerBitmap(bounds, space, flags,
|
||||||
bytesPerRow);
|
bytesPerRow);
|
||||||
if (bitmap == NULL) {
|
if (bitmap == NULL) {
|
||||||
if (overlayToken != NULL)
|
if (overlayToken != NULL)
|
||||||
@ -121,11 +114,10 @@ BitmapManager::CreateBitmap(ClientMemoryAllocator* allocator,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* cookie = NULL;
|
|
||||||
uint8* buffer = NULL;
|
uint8* buffer = NULL;
|
||||||
|
|
||||||
if (flags & B_BITMAP_WILL_OVERLAY) {
|
if (flags & B_BITMAP_WILL_OVERLAY) {
|
||||||
Overlay* overlay = new (std::nothrow) Overlay(hwInterface, bitmap,
|
Overlay* overlay = new(std::nothrow) Overlay(hwInterface, bitmap,
|
||||||
overlayToken);
|
overlayToken);
|
||||||
|
|
||||||
overlay_client_data* clientData = NULL;
|
overlay_client_data* clientData = NULL;
|
||||||
@ -134,32 +126,29 @@ BitmapManager::CreateBitmap(ClientMemoryAllocator* allocator,
|
|||||||
if (overlay != NULL && overlay->InitCheck() == B_OK) {
|
if (overlay != NULL && overlay->InitCheck() == B_OK) {
|
||||||
// allocate client memory to communicate the overlay semaphore
|
// allocate client memory to communicate the overlay semaphore
|
||||||
// and buffer location to the BBitmap
|
// and buffer location to the BBitmap
|
||||||
cookie = allocator->Allocate(sizeof(overlay_client_data),
|
clientData = (overlay_client_data*)bitmap->fClientMemory.Allocate(
|
||||||
(void**)&clientData, newArea);
|
allocator, sizeof(overlay_client_data), newArea);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cookie != NULL) {
|
if (clientData != NULL) {
|
||||||
overlay->SetClientData(clientData);
|
overlay->SetClientData(clientData);
|
||||||
|
|
||||||
bitmap->fAllocator = allocator;
|
bitmap->fMemory = &bitmap->fClientMemory;
|
||||||
bitmap->fAllocationCookie = cookie;
|
|
||||||
bitmap->SetOverlay(overlay);
|
bitmap->SetOverlay(overlay);
|
||||||
bitmap->fBytesPerRow = overlay->OverlayBuffer()->bytes_per_row;
|
bitmap->fBytesPerRow = overlay->OverlayBuffer()->bytes_per_row;
|
||||||
|
|
||||||
buffer = (uint8*)overlay->OverlayBuffer()->buffer;
|
buffer = (uint8*)overlay->OverlayBuffer()->buffer;
|
||||||
if (_allocationFlags)
|
if (_allocationFlags)
|
||||||
*_allocationFlags = kFramebuffer | (newArea ? kNewAllocatorArea : 0);
|
*_allocationFlags = kFramebuffer | (newArea ? kNewAllocatorArea : 0);
|
||||||
} else {
|
} else
|
||||||
delete overlay;
|
delete overlay;
|
||||||
allocator->Free(cookie);
|
|
||||||
}
|
|
||||||
} else if (allocator != NULL) {
|
} else if (allocator != NULL) {
|
||||||
// standard bitmaps
|
// standard bitmaps
|
||||||
bool newArea;
|
bool newArea;
|
||||||
cookie = allocator->Allocate(bitmap->BitsLength(), (void**)&buffer, newArea);
|
buffer = (uint8*)bitmap->fClientMemory.Allocate(allocator,
|
||||||
if (cookie != NULL) {
|
bitmap->BitsLength(), newArea);
|
||||||
bitmap->fAllocator = allocator;
|
if (buffer != NULL) {
|
||||||
bitmap->fAllocationCookie = cookie;
|
bitmap->fMemory = &bitmap->fClientMemory;
|
||||||
|
|
||||||
if (_allocationFlags)
|
if (_allocationFlags)
|
||||||
*_allocationFlags = kAllocator | (newArea ? kNewAllocatorArea : 0);
|
*_allocationFlags = kAllocator | (newArea ? kNewAllocatorArea : 0);
|
||||||
@ -168,8 +157,7 @@ BitmapManager::CreateBitmap(ClientMemoryAllocator* allocator,
|
|||||||
// server side only bitmaps
|
// server side only bitmaps
|
||||||
buffer = (uint8*)malloc(bitmap->BitsLength());
|
buffer = (uint8*)malloc(bitmap->BitsLength());
|
||||||
if (buffer != NULL) {
|
if (buffer != NULL) {
|
||||||
bitmap->fAllocator = NULL;
|
bitmap->fMemory = NULL;
|
||||||
bitmap->fAllocationCookie = NULL;
|
|
||||||
|
|
||||||
if (_allocationFlags)
|
if (_allocationFlags)
|
||||||
*_allocationFlags = kHeap;
|
*_allocationFlags = kHeap;
|
||||||
@ -202,6 +190,37 @@ BitmapManager::CreateBitmap(ClientMemoryAllocator* allocator,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ServerBitmap*
|
||||||
|
BitmapManager::CloneFromClient(area_id clientArea, int32 areaOffset,
|
||||||
|
BRect bounds, color_space space, uint32 flags, int32 bytesPerRow)
|
||||||
|
{
|
||||||
|
BAutolock locker(fLock);
|
||||||
|
if (!locker.IsLocked())
|
||||||
|
return NULL;
|
||||||
|
ServerBitmap* bitmap = new(std::nothrow) ServerBitmap(bounds, space, flags,
|
||||||
|
bytesPerRow);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
bitmap->fMemory = memory;
|
||||||
|
bitmap->fBuffer = memory->Address();
|
||||||
|
bitmap->fToken = gTokenSpace.NewToken(kBitmapToken, bitmap);
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Called when a ServerBitmap is deleted.
|
/*! \brief Called when a ServerBitmap is deleted.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
|
@ -33,6 +33,11 @@ public:
|
|||||||
int32 screen = B_MAIN_SCREEN_ID.id,
|
int32 screen = B_MAIN_SCREEN_ID.id,
|
||||||
uint8* _allocationFlags = NULL);
|
uint8* _allocationFlags = NULL);
|
||||||
|
|
||||||
|
ServerBitmap* CloneFromClient(area_id clientArea,
|
||||||
|
int32 areaOffset, BRect bounds,
|
||||||
|
color_space space, uint32 flags,
|
||||||
|
int32 bytesPerRow = -1);
|
||||||
|
|
||||||
void BitmapRemoved(ServerBitmap* bitmap);
|
void BitmapRemoved(ServerBitmap* bitmap);
|
||||||
|
|
||||||
void SuspendOverlays();
|
void SuspendOverlays();
|
||||||
|
@ -35,8 +35,7 @@ typedef chunk_list::Iterator chunk_iterator;
|
|||||||
|
|
||||||
ClientMemoryAllocator::ClientMemoryAllocator(ServerApp* application)
|
ClientMemoryAllocator::ClientMemoryAllocator(ServerApp* application)
|
||||||
:
|
:
|
||||||
fApplication(application),
|
fApplication(application)
|
||||||
fLock("client memory lock")
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,15 +63,8 @@ ClientMemoryAllocator::~ClientMemoryAllocator()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
ClientMemoryAllocator::InitCheck()
|
|
||||||
{
|
|
||||||
return fLock.InitCheck() < B_OK ? fLock.InitCheck() : B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void*
|
void*
|
||||||
ClientMemoryAllocator::Allocate(size_t size, void** _address, bool& newArea)
|
ClientMemoryAllocator::Allocate(size_t size, block** _address, bool& newArea)
|
||||||
{
|
{
|
||||||
// Search best matching free block from the list
|
// Search best matching free block from the list
|
||||||
|
|
||||||
@ -100,8 +92,8 @@ ClientMemoryAllocator::Allocate(size_t size, void** _address, bool& newArea)
|
|||||||
if (best->size == size) {
|
if (best->size == size) {
|
||||||
// The simple case: the free block has exactly the size we wanted to have
|
// The simple case: the free block has exactly the size we wanted to have
|
||||||
fFreeBlocks.Remove(best);
|
fFreeBlocks.Remove(best);
|
||||||
*_address = best->base;
|
*_address = best;
|
||||||
return best;
|
return best->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: maybe we should have the user reserve memory in its object
|
// TODO: maybe we should have the user reserve memory in its object
|
||||||
@ -118,19 +110,17 @@ ClientMemoryAllocator::Allocate(size_t size, void** _address, bool& newArea)
|
|||||||
best->base += size;
|
best->base += size;
|
||||||
best->size -= size;
|
best->size -= size;
|
||||||
|
|
||||||
*_address = usedBlock->base;
|
*_address = usedBlock;
|
||||||
return usedBlock;
|
return usedBlock->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ClientMemoryAllocator::Free(void* cookie)
|
ClientMemoryAllocator::Free(block* freeBlock)
|
||||||
{
|
{
|
||||||
if (cookie == NULL)
|
if (freeBlock == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
struct block* freeBlock = (struct block*)cookie;
|
|
||||||
|
|
||||||
// search for an adjacent free block
|
// search for an adjacent free block
|
||||||
|
|
||||||
block_iterator iterator = fFreeBlocks.GetIterator();
|
block_iterator iterator = fFreeBlocks.GetIterator();
|
||||||
@ -185,49 +175,9 @@ ClientMemoryAllocator::Free(void* cookie)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
area_id
|
|
||||||
ClientMemoryAllocator::Area(void* cookie)
|
|
||||||
{
|
|
||||||
struct block* block = (struct block*)cookie;
|
|
||||||
|
|
||||||
if (block != NULL)
|
|
||||||
return block->chunk->area;
|
|
||||||
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32
|
|
||||||
ClientMemoryAllocator::AreaOffset(void* cookie)
|
|
||||||
{
|
|
||||||
struct block* block = (struct block*)cookie;
|
|
||||||
|
|
||||||
if (block != NULL)
|
|
||||||
return block->base - block->chunk->base;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
ClientMemoryAllocator::Lock()
|
|
||||||
{
|
|
||||||
return fLock.ReadLock();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
ClientMemoryAllocator::Unlock()
|
|
||||||
{
|
|
||||||
fLock.ReadUnlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ClientMemoryAllocator::Dump()
|
ClientMemoryAllocator::Dump()
|
||||||
{
|
{
|
||||||
AutoReadLocker locker(fLock);
|
|
||||||
|
|
||||||
debug_printf("Application %ld, %s: chunks:\n", fApplication->ClientTeam(),
|
debug_printf("Application %ld, %s: chunks:\n", fApplication->ClientTeam(),
|
||||||
fApplication->Signature());
|
fApplication->Signature());
|
||||||
|
|
||||||
@ -333,3 +283,101 @@ ClientMemoryAllocator::_AllocateChunk(size_t size, bool& newArea)
|
|||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ClientMemory::ClientMemory()
|
||||||
|
:
|
||||||
|
fBlock(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ClientMemory::~ClientMemory()
|
||||||
|
{
|
||||||
|
if (fBlock != NULL)
|
||||||
|
fAllocator->Free(fBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void*
|
||||||
|
ClientMemory::Allocate(ClientMemoryAllocator* allocator, size_t size,
|
||||||
|
bool& newArea)
|
||||||
|
{
|
||||||
|
fAllocator = allocator;
|
||||||
|
return fAllocator->Allocate(size, &fBlock, newArea);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
area_id
|
||||||
|
ClientMemory::Area()
|
||||||
|
{
|
||||||
|
if (fBlock != NULL)
|
||||||
|
return fBlock->chunk->area;
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8*
|
||||||
|
ClientMemory::Address()
|
||||||
|
{
|
||||||
|
if (fBlock != NULL)
|
||||||
|
return fBlock->base;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32
|
||||||
|
ClientMemory::AreaOffset()
|
||||||
|
{
|
||||||
|
if (fBlock != NULL)
|
||||||
|
return fBlock->base - fBlock->chunk->base;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ClonedAreaMemory::ClonedAreaMemory()
|
||||||
|
:
|
||||||
|
fClonedArea(-1),
|
||||||
|
fOffset(0),
|
||||||
|
fBase(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ClonedAreaMemory::~ClonedAreaMemory()
|
||||||
|
{
|
||||||
|
if (fClonedArea >= 0)
|
||||||
|
delete_area(fClonedArea);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void*
|
||||||
|
ClonedAreaMemory::Clone(area_id area, uint32 offset)
|
||||||
|
{
|
||||||
|
fClonedArea = clone_area("server_memory", (void**)&fBase, B_ANY_ADDRESS,
|
||||||
|
B_READ_AREA | B_WRITE_AREA, area);
|
||||||
|
if (fBase == NULL)
|
||||||
|
return NULL;
|
||||||
|
fOffset = offset;
|
||||||
|
return Address();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
area_id
|
||||||
|
ClonedAreaMemory::Area()
|
||||||
|
{
|
||||||
|
return fClonedArea;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8*
|
||||||
|
ClonedAreaMemory::Address()
|
||||||
|
{
|
||||||
|
return fBase + fOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32
|
||||||
|
ClonedAreaMemory::AreaOffset()
|
||||||
|
{
|
||||||
|
return fOffset;
|
||||||
|
}
|
||||||
|
@ -39,17 +39,9 @@ public:
|
|||||||
ClientMemoryAllocator(ServerApp* application);
|
ClientMemoryAllocator(ServerApp* application);
|
||||||
~ClientMemoryAllocator();
|
~ClientMemoryAllocator();
|
||||||
|
|
||||||
status_t InitCheck();
|
void* Allocate(size_t size, block** _address,
|
||||||
|
|
||||||
void* Allocate(size_t size, void** _address,
|
|
||||||
bool& newArea);
|
bool& newArea);
|
||||||
void Free(void* cookie);
|
void Free(block* cookie);
|
||||||
|
|
||||||
area_id Area(void* cookie);
|
|
||||||
uint32 AreaOffset(void* cookie);
|
|
||||||
|
|
||||||
bool Lock();
|
|
||||||
void Unlock();
|
|
||||||
|
|
||||||
void Dump();
|
void Dump();
|
||||||
|
|
||||||
@ -58,10 +50,57 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
ServerApp* fApplication;
|
ServerApp* fApplication;
|
||||||
MultiLocker fLock;
|
|
||||||
chunk_list fChunks;
|
chunk_list fChunks;
|
||||||
block_list fFreeBlocks;
|
block_list fFreeBlocks;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class AreaMemory {
|
||||||
|
public:
|
||||||
|
virtual ~AreaMemory() {}
|
||||||
|
|
||||||
|
virtual area_id Area() = 0;
|
||||||
|
virtual uint8* Address() = 0;
|
||||||
|
virtual uint32 AreaOffset() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ClientMemory : public AreaMemory {
|
||||||
|
public:
|
||||||
|
ClientMemory();
|
||||||
|
|
||||||
|
virtual ~ClientMemory();
|
||||||
|
|
||||||
|
void* Allocate(ClientMemoryAllocator* allocator,
|
||||||
|
size_t size, bool& newArea);
|
||||||
|
|
||||||
|
virtual area_id Area();
|
||||||
|
virtual uint8* Address();
|
||||||
|
virtual uint32 AreaOffset();
|
||||||
|
|
||||||
|
private:
|
||||||
|
ClientMemoryAllocator* fAllocator;
|
||||||
|
block* fBlock;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*! Just clones an existing area. */
|
||||||
|
class ClonedAreaMemory : public AreaMemory{
|
||||||
|
public:
|
||||||
|
ClonedAreaMemory();
|
||||||
|
virtual ~ClonedAreaMemory();
|
||||||
|
|
||||||
|
void* Clone(area_id area, uint32 offset);
|
||||||
|
|
||||||
|
virtual area_id Area();
|
||||||
|
virtual uint8* Address();
|
||||||
|
virtual uint32 AreaOffset();
|
||||||
|
|
||||||
|
private:
|
||||||
|
area_id fClonedArea;
|
||||||
|
uint32 fOffset;
|
||||||
|
uint8* fBase;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif /* CLIENT_MEMORY_ALLOCATOR_H */
|
#endif /* CLIENT_MEMORY_ALLOCATOR_H */
|
||||||
|
@ -59,8 +59,7 @@ using namespace BPrivate;
|
|||||||
ServerBitmap::ServerBitmap(BRect rect, color_space space, uint32 flags,
|
ServerBitmap::ServerBitmap(BRect rect, color_space space, uint32 flags,
|
||||||
int32 bytesPerRow, screen_id screen)
|
int32 bytesPerRow, screen_id screen)
|
||||||
:
|
:
|
||||||
fAllocator(NULL),
|
fMemory(NULL),
|
||||||
fAllocationCookie(NULL),
|
|
||||||
fOverlay(NULL),
|
fOverlay(NULL),
|
||||||
fBuffer(NULL),
|
fBuffer(NULL),
|
||||||
// WARNING: '1' is added to the width and height.
|
// WARNING: '1' is added to the width and height.
|
||||||
@ -84,8 +83,7 @@ ServerBitmap::ServerBitmap(BRect rect, color_space space, uint32 flags,
|
|||||||
//! Copy constructor does not copy the buffer.
|
//! Copy constructor does not copy the buffer.
|
||||||
ServerBitmap::ServerBitmap(const ServerBitmap* bitmap)
|
ServerBitmap::ServerBitmap(const ServerBitmap* bitmap)
|
||||||
:
|
:
|
||||||
fAllocator(NULL),
|
fMemory(NULL),
|
||||||
fAllocationCookie(NULL),
|
|
||||||
fOverlay(NULL),
|
fOverlay(NULL),
|
||||||
fBuffer(NULL),
|
fBuffer(NULL),
|
||||||
fOwner(NULL)
|
fOwner(NULL)
|
||||||
@ -108,9 +106,10 @@ ServerBitmap::ServerBitmap(const ServerBitmap* bitmap)
|
|||||||
|
|
||||||
ServerBitmap::~ServerBitmap()
|
ServerBitmap::~ServerBitmap()
|
||||||
{
|
{
|
||||||
if (fAllocator != NULL)
|
if (fMemory != NULL) {
|
||||||
fAllocator->Free(AllocationCookie());
|
if (fMemory != &fClientMemory)
|
||||||
else
|
delete fMemory;
|
||||||
|
} else
|
||||||
delete[] fBuffer;
|
delete[] fBuffer;
|
||||||
|
|
||||||
delete fOverlay;
|
delete fOverlay;
|
||||||
@ -162,8 +161,8 @@ ServerBitmap::ImportBits(const void *bits, int32 bitsLength, int32 bytesPerRow,
|
|||||||
area_id
|
area_id
|
||||||
ServerBitmap::Area() const
|
ServerBitmap::Area() const
|
||||||
{
|
{
|
||||||
if (fAllocator != NULL)
|
if (fMemory != NULL)
|
||||||
return fAllocator->Area(AllocationCookie());
|
return fMemory->Area();
|
||||||
|
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
@ -172,8 +171,8 @@ ServerBitmap::Area() const
|
|||||||
uint32
|
uint32
|
||||||
ServerBitmap::AreaOffset() const
|
ServerBitmap::AreaOffset() const
|
||||||
{
|
{
|
||||||
if (fAllocator != NULL)
|
if (fMemory != NULL)
|
||||||
return fAllocator->AreaOffset(AllocationCookie());
|
return fMemory->AreaOffset();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,10 @@
|
|||||||
|
|
||||||
#include <Referenceable.h>
|
#include <Referenceable.h>
|
||||||
|
|
||||||
|
#include "ClientMemoryAllocator.h"
|
||||||
|
|
||||||
|
|
||||||
class BitmapManager;
|
class BitmapManager;
|
||||||
class ClientMemoryAllocator;
|
|
||||||
class HWInterface;
|
class HWInterface;
|
||||||
class Overlay;
|
class Overlay;
|
||||||
class ServerApp;
|
class ServerApp;
|
||||||
@ -60,9 +61,6 @@ public:
|
|||||||
inline int32 Token() const
|
inline int32 Token() const
|
||||||
{ return fToken; }
|
{ return fToken; }
|
||||||
|
|
||||||
inline void* AllocationCookie() const
|
|
||||||
{ return fAllocationCookie; }
|
|
||||||
|
|
||||||
area_id Area() const;
|
area_id Area() const;
|
||||||
uint32 AreaOffset() const;
|
uint32 AreaOffset() const;
|
||||||
|
|
||||||
@ -96,8 +94,8 @@ protected:
|
|||||||
void AllocateBuffer();
|
void AllocateBuffer();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ClientMemoryAllocator* fAllocator;
|
ClientMemory fClientMemory;
|
||||||
void* fAllocationCookie;
|
AreaMemory* fMemory;
|
||||||
::Overlay* fOverlay;
|
::Overlay* fOverlay;
|
||||||
uint8* fBuffer;
|
uint8* fBuffer;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user