xref: /haiku/src/servers/app/ServerBitmap.cpp (revision 8eafd6cd04e4d540cbad2ef07f9eb58a297a3b30)
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 	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.
84 ServerBitmap::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 
107 ServerBitmap::~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 */
122 void
123 ServerBitmap::AllocateBuffer()
124 {
125 	uint32 length = BitsLength();
126 	if (length > 0) {
127 		delete[] fBuffer;
128 		fBuffer = new(std::nothrow) uint8[length];
129 	}
130 }
131 
132 
133 status_t
134 ServerBitmap::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 
145 status_t
146 ServerBitmap::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 
158 area_id
159 ServerBitmap::Area() const
160 {
161 	if (fMemory != NULL)
162 		return fMemory->Area();
163 
164 	return B_ERROR;
165 }
166 
167 
168 uint32
169 ServerBitmap::AreaOffset() const
170 {
171 	if (fMemory != NULL)
172 		return fMemory->AreaOffset();
173 
174 	return 0;
175 }
176 
177 
178 void
179 ServerBitmap::SetOverlay(::Overlay* overlay)
180 {
181 	fOverlay.SetTo(overlay);
182 }
183 
184 
185 ::Overlay*
186 ServerBitmap::Overlay() const
187 {
188 	return fOverlay.Get();
189 }
190 
191 
192 void
193 ServerBitmap::SetOwner(ServerApp* owner)
194 {
195 	fOwner = owner;
196 }
197 
198 
199 ServerApp*
200 ServerBitmap::Owner() const
201 {
202 	return fOwner;
203 }
204 
205 
206 void
207 ServerBitmap::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 
218 UtilityBitmap::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 
227 UtilityBitmap::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 
238 UtilityBitmap::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 
249 UtilityBitmap::~UtilityBitmap()
250 {
251 }
252