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