xref: /haiku/src/servers/app/ServerBitmap.cpp (revision e81a954787e50e56a7f06f72705b7859b6ab06d1)
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 	delete fOverlay;
116 		// deleting the overlay will also free the overlay buffer
117 }
118 
119 
120 /*!	\brief Internal function used by subclasses
121 
122 	Subclasses should call this so the buffer can automagically
123 	be allocated on the heap.
124 */
125 void
126 ServerBitmap::AllocateBuffer()
127 {
128 	uint32 length = BitsLength();
129 	if (length > 0) {
130 		delete[] fBuffer;
131 		fBuffer = new(std::nothrow) uint8[length];
132 	}
133 }
134 
135 
136 status_t
137 ServerBitmap::ImportBits(const void *bits, int32 bitsLength, int32 bytesPerRow,
138 	color_space colorSpace)
139 {
140 	if (!bits || bitsLength < 0 || bytesPerRow <= 0)
141 		return B_BAD_VALUE;
142 
143 	return BPrivate::ConvertBits(bits, fBuffer, bitsLength, BitsLength(),
144 		bytesPerRow, fBytesPerRow, colorSpace, fSpace, fWidth, fHeight);
145 }
146 
147 
148 status_t
149 ServerBitmap::ImportBits(const void *bits, int32 bitsLength, int32 bytesPerRow,
150 	color_space colorSpace, BPoint from, BPoint to, int32 width, int32 height)
151 {
152 	if (!bits || bitsLength < 0 || bytesPerRow <= 0 || width < 0 || height < 0)
153 		return B_BAD_VALUE;
154 
155 	return BPrivate::ConvertBits(bits, fBuffer, bitsLength, BitsLength(),
156 		bytesPerRow, fBytesPerRow, colorSpace, fSpace, from, to, width,
157 		height);
158 }
159 
160 
161 area_id
162 ServerBitmap::Area() const
163 {
164 	if (fMemory != NULL)
165 		return fMemory->Area();
166 
167 	return B_ERROR;
168 }
169 
170 
171 uint32
172 ServerBitmap::AreaOffset() const
173 {
174 	if (fMemory != NULL)
175 		return fMemory->AreaOffset();
176 
177 	return 0;
178 }
179 
180 
181 void
182 ServerBitmap::SetOverlay(::Overlay* overlay)
183 {
184 	fOverlay = overlay;
185 }
186 
187 
188 ::Overlay*
189 ServerBitmap::Overlay() const
190 {
191 	return fOverlay;
192 }
193 
194 
195 void
196 ServerBitmap::SetOwner(ServerApp* owner)
197 {
198 	fOwner = owner;
199 }
200 
201 
202 ServerApp*
203 ServerBitmap::Owner() const
204 {
205 	return fOwner;
206 }
207 
208 
209 void
210 ServerBitmap::PrintToStream()
211 {
212 	printf("Bitmap@%p: (%" B_PRId32 ":%" B_PRId32 "), space %" B_PRId32 ", "
213 		"bpr %" B_PRId32 ", buffer %p\n", this, fWidth, fHeight, (int32)fSpace,
214 		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