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