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