xref: /haiku/src/servers/app/ServerBitmap.cpp (revision 481f986b59e7782458dcc5fe98ad59a57480e5db)
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 
27 using std::nothrow;
28 using 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 */
59 ServerBitmap::ServerBitmap(BRect rect, color_space space, uint32 flags,
60 		int32 bytesPerRow, screen_id screen)
61 	:
62 	fAllocator(NULL),
63 	fAllocationCookie(NULL),
64 	fOverlay(NULL),
65 	fBuffer(NULL),
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 	fOwner(NULL)
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 	} else {
100 		fWidth = 0;
101 		fHeight = 0;
102 		fBytesPerRow = 0;
103 		fSpace = B_NO_COLOR_SPACE;
104 		fFlags = 0;
105 	}
106 }
107 
108 
109 ServerBitmap::~ServerBitmap()
110 {
111 	if (fAllocator != NULL)
112 		fAllocator->Free(AllocationCookie());
113 	else
114 		delete[] fBuffer;
115 
116 	delete fOverlay;
117 		// deleting the overlay will also free the overlay buffer
118 }
119 
120 
121 /*!	\brief Internal function used by subclasses
122 
123 	Subclasses should call this so the buffer can automagically
124 	be allocated on the heap.
125 */
126 void
127 ServerBitmap::AllocateBuffer()
128 {
129 	uint32 length = BitsLength();
130 	if (length > 0) {
131 		delete[] fBuffer;
132 		fBuffer = new(std::nothrow) uint8[length];
133 	}
134 }
135 
136 
137 status_t
138 ServerBitmap::ImportBits(const void *bits, int32 bitsLength, int32 bytesPerRow,
139 	color_space colorSpace)
140 {
141 	if (!bits || bitsLength < 0 || bytesPerRow <= 0)
142 		return B_BAD_VALUE;
143 
144 	return BPrivate::ConvertBits(bits, fBuffer, bitsLength, BitsLength(),
145 		bytesPerRow, fBytesPerRow, colorSpace, fSpace, fWidth, fHeight);
146 }
147 
148 
149 status_t
150 ServerBitmap::ImportBits(const void *bits, int32 bitsLength, int32 bytesPerRow,
151 	color_space colorSpace, BPoint from, BPoint to, int32 width, int32 height)
152 {
153 	if (!bits || bitsLength < 0 || bytesPerRow <= 0 || width < 0 || height < 0)
154 		return B_BAD_VALUE;
155 
156 	return BPrivate::ConvertBits(bits, fBuffer, bitsLength, BitsLength(),
157 		bytesPerRow, fBytesPerRow, colorSpace, fSpace, from, to, width,
158 		height);
159 }
160 
161 
162 area_id
163 ServerBitmap::Area() const
164 {
165 	if (fAllocator != NULL)
166 		return fAllocator->Area(AllocationCookie());
167 
168 	return B_ERROR;
169 }
170 
171 
172 uint32
173 ServerBitmap::AreaOffset() const
174 {
175 	if (fAllocator != NULL)
176 		return fAllocator->AreaOffset(AllocationCookie());
177 
178 	return 0;
179 }
180 
181 
182 void
183 ServerBitmap::SetOverlay(::Overlay* overlay)
184 {
185 	fOverlay = overlay;
186 }
187 
188 
189 ::Overlay*
190 ServerBitmap::Overlay() const
191 {
192 	return fOverlay;
193 }
194 
195 
196 void
197 ServerBitmap::SetOwner(ServerApp* owner)
198 {
199 	fOwner = owner;
200 }
201 
202 
203 ServerApp*
204 ServerBitmap::Owner() const
205 {
206 	return fOwner;
207 }
208 
209 
210 void
211 ServerBitmap::PrintToStream()
212 {
213 	printf("Bitmap@%p: (%ld:%ld), space %ld, bpr %ld, buffer %p\n",
214 		this, fWidth, fHeight, (int32)fSpace, fBytesPerRow, fBuffer);
215 }
216 
217 
218 //	#pragma mark -
219 
220 
221 UtilityBitmap::UtilityBitmap(BRect rect, color_space space, uint32 flags,
222 		int32 bytesPerRow, screen_id screen)
223 	:
224 	ServerBitmap(rect, space, flags, bytesPerRow, screen)
225 {
226 	AllocateBuffer();
227 }
228 
229 
230 UtilityBitmap::UtilityBitmap(const ServerBitmap* bitmap)
231 	:
232 	ServerBitmap(bitmap)
233 {
234 	AllocateBuffer();
235 
236 	if (bitmap->Bits())
237 		memcpy(Bits(), bitmap->Bits(), bitmap->BitsLength());
238 }
239 
240 
241 UtilityBitmap::UtilityBitmap(const uint8* alreadyPaddedData, uint32 width,
242 		uint32 height, color_space format)
243 	:
244 	ServerBitmap(BRect(0, 0, width - 1, height - 1), format, 0)
245 {
246 	AllocateBuffer();
247 	if (Bits())
248 		memcpy(Bits(), alreadyPaddedData, BitsLength());
249 }
250 
251 
252 UtilityBitmap::~UtilityBitmap()
253 {
254 }
255