14acb99b6SAxel Dörfler/*
287e7b978SAxel Dörfler * Copyright 2001-2010, Haiku.
34acb99b6SAxel Dörfler * Distributed under the terms of the MIT License.
44acb99b6SAxel Dörfler *
54acb99b6SAxel Dörfler * Authors:
64acb99b6SAxel Dörfler *		DarkWyrm <bpmagic@columbus.rr.com>
721c8c925SAxel Dörfler *		Axel D��rfler, axeld@pinc-software.de
84acb99b6SAxel Dörfler */
975d26e10SStephan Aßmus
10758b1d0eSIngo Weinhold
11cd5337c0SDarkWyrm#include "ServerBitmap.h"
1221c8c925SAxel Dörfler
134acb99b6SAxel Dörfler#include <new>
14aa1f5437SAxel Dörfler#include <stdio.h>
159781d591SIngo Weinhold#include <stdlib.h>
164acb99b6SAxel Dörfler#include <string.h>
174acb99b6SAxel Dörfler
1885a7877fSAxel Dörfler#include "BitmapManager.h"
1942ed4fd7SStephan Aßmus#include "ClientMemoryAllocator.h"
2042ed4fd7SStephan Aßmus#include "ColorConversion.h"
2142ed4fd7SStephan Aßmus#include "HWInterface.h"
22ab53bb20SStefano Ceccherini#include "InterfacePrivate.h"
2342ed4fd7SStephan Aßmus#include "Overlay.h"
2485a7877fSAxel Dörfler#include "ServerApp.h"
2585a7877fSAxel Dörfler
2642ed4fd7SStephan Aßmus
27758b1d0eSIngo Weinholdusing std::nothrow;
28ab53bb20SStefano Ceccheriniusing namespace BPrivate;
29758b1d0eSIngo Weinhold
3063c07622SAxel Dörfler
3187e7b978SAxel Dörfler/*!	A word about memory housekeeping and why it's implemented this way:
3237b502f2SAxel Dörfler
3337b502f2SAxel Dörfler	The reason why this looks so complicated is to optimize the most common
3437b502f2SAxel Dörfler	path (bitmap creation from the application), and don't cause any further
3537b502f2SAxel Dörfler	memory allocations for maintaining memory in that case.
3663c07622SAxel Dörfler	If a bitmap was allocated this way, both, the fAllocator and
3763c07622SAxel Dörfler	fAllocationCookie members are used.
3837b502f2SAxel Dörfler
3921c8c925SAxel Dörfler	For overlays, the allocator only allocates a small piece of client memory
4021c8c925SAxel Dörfler	for use with the overlay_client_data structure - the actual buffer will be
4121c8c925SAxel Dörfler	placed in the graphics frame buffer and is allocated by the graphics driver.
4237b502f2SAxel Dörfler
4337b502f2SAxel Dörfler	If the memory was allocated on the app_server heap, neither fAllocator, nor
4437b502f2SAxel Dörfler	fAllocationCookie are used, and the buffer is just freed in that case when
4537b502f2SAxel Dörfler	the bitmap is destructed. This method is mainly used for cursors.
4637b502f2SAxel Dörfler*/
4737b502f2SAxel Dörfler
484acb99b6SAxel Dörfler
4987e7b978SAxel Dörfler/*!	\brief Constructor called by the BitmapManager (only).
50c37002b4SDarkWyrm	\param rect Size of the bitmap.
51c37002b4SDarkWyrm	\param space Color space of the bitmap
52c37002b4SDarkWyrm	\param flags Various bitmap flags to tweak the bitmap as defined in Bitmap.h
5363c07622SAxel Dörfler	\param bytesperline Number of bytes in each row. -1 implies the default
5463c07622SAxel Dörfler		value. Any value less than the the default will less than the default
5563c07622SAxel Dörfler		will be overridden, but any value greater than the default will result
5663c07622SAxel Dörfler		in the number of bytes specified.
57c37002b4SDarkWyrm	\param screen Screen assigned to the bitmap.
59dcd70f0eSStephan AßmusServerBitmap::ServerBitmap(BRect rect, color_space space, uint32 flags,
60dcd70f0eSStephan Aßmus		int32 bytesPerRow, screen_id screen)
6121c8c925SAxel Dörfler	:
62577f5876Sczeidler	fMemory(NULL),
630ac013e6SAxel Dörfler	fOverlay(NULL),
6421c8c925SAxel Dörfler	fBuffer(NULL),
6521c8c925SAxel Dörfler	// WARNING: '1' is added to the width and height.
6621c8c925SAxel Dörfler	// Same is done in FBBitmap subclass, so if you
6721c8c925SAxel Dörfler	// modify here make sure to do the same under
6821c8c925SAxel Dörfler	// FBBitmap::SetSize(...)
6921c8c925SAxel Dörfler	fWidth(rect.IntegerWidth() + 1),
7021c8c925SAxel Dörfler	fHeight(rect.IntegerHeight() + 1),
7121c8c925SAxel Dörfler	fBytesPerRow(0),
7221c8c925SAxel Dörfler	fSpace(space),
7321c8c925SAxel Dörfler	fFlags(flags),
7487e7b978SAxel Dörfler	fOwner(NULL)
7521c8c925SAxel Dörfler	// fToken is initialized (if used) by the BitmapManager
77ab53bb20SStefano Ceccherini	int32 minBytesPerRow = get_bytes_per_row(space, fWidth);
7863c07622SAxel Dörfler
79ab53bb20SStefano Ceccherini	fBytesPerRow = max_c(bytesPerRow, minBytesPerRow);
824acb99b6SAxel Dörfler
83cd5337c0SDarkWyrm//! Copy constructor does not copy the buffer.
84117b384eSAxel DörflerServerBitmap::ServerBitmap(const ServerBitmap* bitmap)
8521c8c925SAxel Dörfler	:
86577f5876Sczeidler	fMemory(NULL),
870ac013e6SAxel Dörfler	fOverlay(NULL),
8821c8c925SAxel Dörfler	fBuffer(NULL),
8987e7b978SAxel Dörfler	fOwner(NULL)
91117b384eSAxel Dörfler	if (bitmap) {
9263c07622SAxel Dörfler		fWidth = bitmap->fWidth;
9363c07622SAxel Dörfler		fHeight = bitmap->fHeight;
9463c07622SAxel Dörfler		fBytesPerRow = bitmap->fBytesPerRow;
9563c07622SAxel Dörfler		fSpace = bitmap->fSpace;
9663c07622SAxel Dörfler		fFlags = bitmap->fFlags;
97ec668ad7SStephan Aßmus	} else {
9863c07622SAxel Dörfler		fWidth = 0;
9963c07622SAxel Dörfler		fHeight = 0;
10063c07622SAxel Dörfler		fBytesPerRow = 0;
10163c07622SAxel Dörfler		fSpace = B_NO_COLOR_SPACE;
10263c07622SAxel Dörfler		fFlags = 0;
103cd5337c0SDarkWyrm	}
1064acb99b6SAxel Dörfler
107ec668ad7SStephan AßmusServerBitmap::~ServerBitmap()
109577f5876Sczeidler	if (fMemory != NULL) {
110577f5876Sczeidler		if (fMemory != &fClientMemory)
111577f5876Sczeidler			delete fMemory;
112577f5876Sczeidler	} else
113ba823bcbSStefano Ceccherini		delete[] fBuffer;
11421c8c925SAxel Dörfler
1150ac013e6SAxel Dörfler	delete fOverlay;
1160ac013e6SAxel Dörfler		// deleting the overlay will also free the overlay buffer
1194acb99b6SAxel Dörfler
12063c07622SAxel Dörfler/*!	\brief Internal function used by subclasses
12163c07622SAxel Dörfler
122eee27b42SDarkWyrm	Subclasses should call this so the buffer can automagically
123eee27b42SDarkWyrm	be allocated on the heap.
125ec668ad7SStephan Aßmusvoid
1264b0459b2SAxel DörflerServerBitmap::AllocateBuffer()
128ec668ad7SStephan Aßmus	uint32 length = BitsLength();
129ec668ad7SStephan Aßmus	if (length > 0) {
130f39e1df2SStefano Ceccherini		delete[] fBuffer;
1314b0459b2SAxel Dörfler		fBuffer = new(std::nothrow) uint8[length];
132ec668ad7SStephan Aßmus	}
1354acb99b6SAxel Dörfler
136acfad792SMichael Lotzstatus_t
137acfad792SMichael LotzServerBitmap::ImportBits(const void *bits, int32 bitsLength, int32 bytesPerRow,
138acfad792SMichael Lotz	color_space colorSpace)
139acfad792SMichael Lotz{
140acfad792SMichael Lotz	if (!bits || bitsLength < 0 || bytesPerRow <= 0)
141acfad792SMichael Lotz		return B_BAD_VALUE;
142acfad792SMichael Lotz
143bdc6f9e7SMichael Lotz	return BPrivate::ConvertBits(bits, fBuffer, bitsLength, BitsLength(),
144bdc6f9e7SMichael Lotz		bytesPerRow, fBytesPerRow, colorSpace, fSpace, fWidth, fHeight);
145acfad792SMichael Lotz}
146acfad792SMichael Lotz
147acfad792SMichael Lotz
148ee18c3ccSMichael Lotzstatus_t
149ee18c3ccSMichael LotzServerBitmap::ImportBits(const void *bits, int32 bitsLength, int32 bytesPerRow,
150ee18c3ccSMichael Lotz	color_space colorSpace, BPoint from, BPoint to, int32 width, int32 height)
151ee18c3ccSMichael Lotz{
152ee18c3ccSMichael Lotz	if (!bits || bitsLength < 0 || bytesPerRow <= 0 || width < 0 || height < 0)
153ee18c3ccSMichael Lotz		return B_BAD_VALUE;
154ee18c3ccSMichael Lotz
155ee18c3ccSMichael Lotz	return BPrivate::ConvertBits(bits, fBuffer, bitsLength, BitsLength(),
1560581480cSMichael Lotz		bytesPerRow, fBytesPerRow, colorSpace, fSpace, from, to, width,
1570581480cSMichael Lotz		height);
158ee18c3ccSMichael Lotz}
159ee18c3ccSMichael Lotz
160ee18c3ccSMichael Lotz
1619a44fdc9SAxel Dörflerarea_id
1629a44fdc9SAxel DörflerServerBitmap::Area() const
1639a44fdc9SAxel Dörfler{
164577f5876Sczeidler	if (fMemory != NULL)
165577f5876Sczeidler		return fMemory->Area();
1669a44fdc9SAxel Dörfler
1679a44fdc9SAxel Dörfler	return B_ERROR;
1689a44fdc9SAxel Dörfler}
1699a44fdc9SAxel Dörfler
1709a44fdc9SAxel Dörfler
1719a44fdc9SAxel Dörfleruint32
1729a44fdc9SAxel DörflerServerBitmap::AreaOffset() const
1739a44fdc9SAxel Dörfler{
174577f5876Sczeidler	if (fMemory != NULL)
175577f5876Sczeidler		return fMemory->AreaOffset();
1769a44fdc9SAxel Dörfler
1779a44fdc9SAxel Dörfler	return 0;
1789a44fdc9SAxel Dörfler}
1799a44fdc9SAxel Dörfler
1809a44fdc9SAxel Dörfler
18121c8c925SAxel Dörflervoid
182117b384eSAxel DörflerServerBitmap::SetOverlay(::Overlay* overlay)
18337b502f2SAxel Dörfler{
184117b384eSAxel Dörfler	fOverlay = overlay;
18521c8c925SAxel Dörfler}
18621c8c925SAxel Dörfler
18737b502f2SAxel Dörfler
1880ac013e6SAxel Dörfler::Overlay*
1890ac013e6SAxel DörflerServerBitmap::Overlay() const
19021c8c925SAxel Dörfler{
1910ac013e6SAxel Dörfler	return fOverlay;
19237b502f2SAxel Dörfler}
19337b502f2SAxel Dörfler
19437b502f2SAxel Dörfler
19587e7b978SAxel Dörflervoid
196117b384eSAxel DörflerServerBitmap::SetOwner(ServerApp* owner)
197117b384eSAxel Dörfler{
19887e7b978SAxel Dörfler	fOwner = owner;
199117b384eSAxel Dörfler}
200117b384eSAxel Dörfler
201117b384eSAxel Dörfler
202117b384eSAxel DörflerServerApp*
203117b384eSAxel DörflerServerBitmap::Owner() const
204117b384eSAxel Dörfler{
205117b384eSAxel Dörfler	return fOwner;
206117b384eSAxel Dörfler}
207117b384eSAxel Dörfler
208117b384eSAxel Dörfler
209aa1f5437SAxel Dörflervoid
210aa1f5437SAxel DörflerServerBitmap::PrintToStream()
211aa1f5437SAxel Dörfler{
2123fed1a15SAlex Smith	printf("Bitmap@%p: (%" B_PRId32 ":%" B_PRId32 "), space %" B_PRId32 ", "
2133fed1a15SAlex Smith		"bpr %" B_PRId32 ", buffer %p\n", this, fWidth, fHeight, (int32)fSpace,
2143fed1a15SAlex Smith		fBytesPerRow, fBuffer);
215aa1f5437SAxel Dörfler}
216aa1f5437SAxel Dörfler
217aa1f5437SAxel Dörfler
2184acb99b6SAxel Dörfler//	#pragma mark -
2194acb99b6SAxel Dörfler
2204acb99b6SAxel Dörfler
221dcd70f0eSStephan AßmusUtilityBitmap::UtilityBitmap(BRect rect, color_space space, uint32 flags,
22287e7b978SAxel Dörfler		int32 bytesPerRow, screen_id screen)
22387e7b978SAxel Dörfler	:
22487e7b978SAxel Dörfler	ServerBitmap(rect, space, flags, bytesPerRow, screen)
225ec668ad7SStephan Aßmus{
2264b0459b2SAxel Dörfler	AllocateBuffer();
2294acb99b6SAxel Dörfler
2309a44fdc9SAxel DörflerUtilityBitmap::UtilityBitmap(const ServerBitmap* bitmap)
23187e7b978SAxel Dörfler	:
23287e7b978SAxel Dörfler	ServerBitmap(bitmap)
2344b0459b2SAxel Dörfler	AllocateBuffer();
2359a44fdc9SAxel Dörfler
2369a44fdc9SAxel Dörfler	if (bitmap->Bits())
2379a44fdc9SAxel Dörfler		memcpy(Bits(), bitmap->Bits(), bitmap->BitsLength());
2404acb99b6SAxel Dörfler
241dcd70f0eSStephan AßmusUtilityBitmap::UtilityBitmap(const uint8* alreadyPaddedData, uint32 width,
242dcd70f0eSStephan Aßmus		uint32 height, color_space format)
24387e7b978SAxel Dörfler	:
24487e7b978SAxel Dörfler	ServerBitmap(BRect(0, 0, width - 1, height - 1), format, 0)
2464b0459b2SAxel Dörfler	AllocateBuffer();
247ec668ad7SStephan Aßmus	if (Bits())
248ec668ad7SStephan Aßmus		memcpy(Bits(), alreadyPaddedData, BitsLength());
2514acb99b6SAxel Dörfler
252ec668ad7SStephan AßmusUtilityBitmap::~UtilityBitmap()