1/*
2 * Copyright 2001-2010, Haiku.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		DarkWyrm <bpmagic@columbus.rr.com>
7 *		Axel D��rfler, axeld@pinc-software.de
8 */
9
10
11#include "ServerBitmap.h"
12
13#include <new>
14#include <stdio.h>
15#include <stdlib.h>
16#include <string.h>
17
18#include "BitmapManager.h"
19#include "ClientMemoryAllocator.h"
20#include "ColorConversion.h"
21#include "HWInterface.h"
22#include "InterfacePrivate.h"
23#include "Overlay.h"
24#include "ServerApp.h"
25
26
27using std::nothrow;
28using namespace BPrivate;
29
30
31/*!	A word about memory housekeeping and why it's implemented this way:
32
33	The reason why this looks so complicated is to optimize the most common
34	path (bitmap creation from the application), and don't cause any further
35	memory allocations for maintaining memory in that case.
36	If a bitmap was allocated this way, both, the fAllocator and
37	fAllocationCookie members are used.
38
39	For overlays, the allocator only allocates a small piece of client memory
40	for use with the overlay_client_data structure - the actual buffer will be
41	placed in the graphics frame buffer and is allocated by the graphics driver.
42
43	If the memory was allocated on the app_server heap, neither fAllocator, nor
44	fAllocationCookie are used, and the buffer is just freed in that case when
45	the bitmap is destructed. This method is mainly used for cursors.
46*/
47
48
49/*!	\brief Constructor called by the BitmapManager (only).
50	\param rect Size of the bitmap.
51	\param space Color space of the bitmap
52	\param flags Various bitmap flags to tweak the bitmap as defined in Bitmap.h
53	\param bytesperline Number of bytes in each row. -1 implies the default
54		value. Any value less than the the default will less than the default
55		will be overridden, but any value greater than the default will result
56		in the number of bytes specified.
57	\param screen Screen assigned to the bitmap.
58*/
59ServerBitmap::ServerBitmap(BRect rect, color_space space, uint32 flags,
60		int32 bytesPerRow, screen_id screen)
61	:
62	fMemory(NULL),
63	fOverlay(NULL),
64	fBuffer(NULL),
65	// WARNING: '1' is added to the width and height.
66	// Same is done in FBBitmap subclass, so if you
67	// modify here make sure to do the same under
68	// FBBitmap::SetSize(...)
69	fWidth(rect.IntegerWidth() + 1),
70	fHeight(rect.IntegerHeight() + 1),
71	fBytesPerRow(0),
72	fSpace(space),
73	fFlags(flags),
74	fOwner(NULL)
75	// fToken is initialized (if used) by the BitmapManager
76{
77	int32 minBytesPerRow = get_bytes_per_row(space, fWidth);
78
79	fBytesPerRow = max_c(bytesPerRow, minBytesPerRow);
80}
81
82
83//! Copy constructor does not copy the buffer.
84ServerBitmap::ServerBitmap(const ServerBitmap* bitmap)
85	:
86	fMemory(NULL),
87	fOverlay(NULL),
88	fBuffer(NULL),
89	fOwner(NULL)
90{
91	if (bitmap) {
92		fWidth = bitmap->fWidth;
93		fHeight = bitmap->fHeight;
94		fBytesPerRow = bitmap->fBytesPerRow;
95		fSpace = bitmap->fSpace;
96		fFlags = bitmap->fFlags;
97	} else {
98		fWidth = 0;
99		fHeight = 0;
100		fBytesPerRow = 0;
101		fSpace = B_NO_COLOR_SPACE;
102		fFlags = 0;
103	}
104}
105
106
107ServerBitmap::~ServerBitmap()
108{
109	if (fMemory != NULL) {
110		if (fMemory != &fClientMemory)
111			delete fMemory;
112	} else
113		delete[] fBuffer;
114}
115
116
117/*!	\brief Internal function used by subclasses
118
119	Subclasses should call this so the buffer can automagically
120	be allocated on the heap.
121*/
122void
123ServerBitmap::AllocateBuffer()
124{
125	uint32 length = BitsLength();
126	if (length > 0) {
127		delete[] fBuffer;
128		fBuffer = new(std::nothrow) uint8[length];
129	}
130}
131
132
133status_t
134ServerBitmap::ImportBits(const void *bits, int32 bitsLength, int32 bytesPerRow,
135	color_space colorSpace)
136{
137	if (!bits || bitsLength < 0 || bytesPerRow <= 0)
138		return B_BAD_VALUE;
139
140	return BPrivate::ConvertBits(bits, fBuffer, bitsLength, BitsLength(),
141		bytesPerRow, fBytesPerRow, colorSpace, fSpace, fWidth, fHeight);
142}
143
144
145status_t
146ServerBitmap::ImportBits(const void *bits, int32 bitsLength, int32 bytesPerRow,
147	color_space colorSpace, BPoint from, BPoint to, int32 width, int32 height)
148{
149	if (!bits || bitsLength < 0 || bytesPerRow <= 0 || width < 0 || height < 0)
150		return B_BAD_VALUE;
151
152	return BPrivate::ConvertBits(bits, fBuffer, bitsLength, BitsLength(),
153		bytesPerRow, fBytesPerRow, colorSpace, fSpace, from, to, width,
154		height);
155}
156
157
158area_id
159ServerBitmap::Area() const
160{
161	if (fMemory != NULL)
162		return fMemory->Area();
163
164	return B_ERROR;
165}
166
167
168uint32
169ServerBitmap::AreaOffset() const
170{
171	if (fMemory != NULL)
172		return fMemory->AreaOffset();
173
174	return 0;
175}
176
177
178void
179ServerBitmap::SetOverlay(::Overlay* overlay)
180{
181	fOverlay.SetTo(overlay);
182}
183
184
185::Overlay*
186ServerBitmap::Overlay() const
187{
188	return fOverlay.Get();
189}
190
191
192void
193ServerBitmap::SetOwner(ServerApp* owner)
194{
195	fOwner = owner;
196}
197
198
199ServerApp*
200ServerBitmap::Owner() const
201{
202	return fOwner;
203}
204
205
206void
207ServerBitmap::PrintToStream()
208{
209	printf("Bitmap@%p: (%" B_PRId32 ":%" B_PRId32 "), space %" B_PRId32 ", "
210		"bpr %" B_PRId32 ", buffer %p\n", this, fWidth, fHeight, (int32)fSpace,
211		fBytesPerRow, fBuffer);
212}
213
214
215//	#pragma mark -
216
217
218UtilityBitmap::UtilityBitmap(BRect rect, color_space space, uint32 flags,
219		int32 bytesPerRow, screen_id screen)
220	:
221	ServerBitmap(rect, space, flags, bytesPerRow, screen)
222{
223	AllocateBuffer();
224}
225
226
227UtilityBitmap::UtilityBitmap(const ServerBitmap* bitmap)
228	:
229	ServerBitmap(bitmap)
230{
231	AllocateBuffer();
232
233	if (bitmap->Bits())
234		memcpy(Bits(), bitmap->Bits(), bitmap->BitsLength());
235}
236
237
238UtilityBitmap::UtilityBitmap(const uint8* alreadyPaddedData, uint32 width,
239		uint32 height, color_space format)
240	:
241	ServerBitmap(BRect(0, 0, width - 1, height - 1), format, 0)
242{
243	AllocateBuffer();
244	if (Bits())
245		memcpy(Bits(), alreadyPaddedData, BitsLength());
246}
247
248
249UtilityBitmap::~UtilityBitmap()
250{
251}
252