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