| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <windows.h> |
| 6 #include <psapi.h> |
| 7 |
| 5 #include "skia/ext/bitmap_platform_device_win.h" | 8 #include "skia/ext/bitmap_platform_device_win.h" |
| 6 | 9 |
| 7 #include "third_party/skia/include/core/SkMatrix.h" | 10 #include "third_party/skia/include/core/SkMatrix.h" |
| 8 #include "third_party/skia/include/core/SkRefCnt.h" | 11 #include "third_party/skia/include/core/SkRefCnt.h" |
| 9 #include "third_party/skia/include/core/SkRegion.h" | 12 #include "third_party/skia/include/core/SkRegion.h" |
| 10 #include "third_party/skia/include/core/SkUtils.h" | 13 #include "third_party/skia/include/core/SkUtils.h" |
| 11 | 14 |
| 12 namespace skia { | 15 namespace skia { |
| 13 | 16 |
| 14 namespace { | 17 namespace { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 35 } | 38 } |
| 36 } else { | 39 } else { |
| 37 // Fill up available size. | 40 // Fill up available size. |
| 38 *size = available_size - *position; | 41 *size = available_size - *position; |
| 39 } | 42 } |
| 40 return true; | 43 return true; |
| 41 } | 44 } |
| 42 | 45 |
| 43 } // namespace | 46 } // namespace |
| 44 | 47 |
| 45 class BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData : public SkRefCnt { | 48 class BitmapPlatformDevice::BitmapPlatformDeviceData : public SkRefCnt { |
| 46 public: | 49 public: |
| 47 explicit BitmapPlatformDeviceWinData(HBITMAP hbitmap); | 50 explicit BitmapPlatformDeviceData(HBITMAP hbitmap); |
| 48 | 51 |
| 49 // Create/destroy hdc_, which is the memory DC for our bitmap data. | 52 // Create/destroy hdc_, which is the memory DC for our bitmap data. |
| 50 HDC GetBitmapDC(); | 53 HDC GetBitmapDC(); |
| 51 void ReleaseBitmapDC(); | 54 void ReleaseBitmapDC(); |
| 52 bool IsBitmapDCCreated() const; | 55 bool IsBitmapDCCreated() const; |
| 53 | 56 |
| 54 // Sets the transform and clip operations. This will not update the DC, | 57 // Sets the transform and clip operations. This will not update the DC, |
| 55 // but will mark the config as dirty. The next call of LoadConfig will | 58 // but will mark the config as dirty. The next call of LoadConfig will |
| 56 // pick up these changes. | 59 // pick up these changes. |
| 57 void SetMatrixClip(const SkMatrix& transform, const SkRegion& region); | 60 void SetMatrixClip(const SkMatrix& transform, const SkRegion& region); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 78 bool config_dirty_; | 81 bool config_dirty_; |
| 79 | 82 |
| 80 // Translation assigned to the DC: we need to keep track of this separately | 83 // Translation assigned to the DC: we need to keep track of this separately |
| 81 // so it can be updated even if the DC isn't created yet. | 84 // so it can be updated even if the DC isn't created yet. |
| 82 SkMatrix transform_; | 85 SkMatrix transform_; |
| 83 | 86 |
| 84 // The current clipping | 87 // The current clipping |
| 85 SkRegion clip_region_; | 88 SkRegion clip_region_; |
| 86 | 89 |
| 87 private: | 90 private: |
| 88 virtual ~BitmapPlatformDeviceWinData(); | 91 virtual ~BitmapPlatformDeviceData(); |
| 89 | 92 |
| 90 // Copy & assign are not supported. | 93 // Copy & assign are not supported. |
| 91 BitmapPlatformDeviceWinData(const BitmapPlatformDeviceWinData&); | 94 BitmapPlatformDeviceData(const BitmapPlatformDeviceData&); |
| 92 BitmapPlatformDeviceWinData& operator=(const BitmapPlatformDeviceWinData&); | 95 BitmapPlatformDeviceData& operator=(const BitmapPlatformDeviceData&); |
| 93 }; | 96 }; |
| 94 | 97 |
| 95 BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData::BitmapPlatformDeviceWinDat
a( | 98 BitmapPlatformDevice::BitmapPlatformDeviceData::BitmapPlatformDeviceData( |
| 96 HBITMAP hbitmap) | 99 HBITMAP hbitmap) |
| 97 : hbitmap_(hbitmap), | 100 : hbitmap_(hbitmap), |
| 98 hdc_(NULL), | 101 hdc_(NULL), |
| 99 config_dirty_(true) { // Want to load the config next time. | 102 config_dirty_(true) { // Want to load the config next time. |
| 100 // Initialize the clip region to the entire bitmap. | 103 // Initialize the clip region to the entire bitmap. |
| 101 BITMAP bitmap_data; | 104 BITMAP bitmap_data; |
| 102 if (GetObject(hbitmap_, sizeof(BITMAP), &bitmap_data)) { | 105 if (GetObject(hbitmap_, sizeof(BITMAP), &bitmap_data)) { |
| 103 SkIRect rect; | 106 SkIRect rect; |
| 104 rect.set(0, 0, bitmap_data.bmWidth, bitmap_data.bmHeight); | 107 rect.set(0, 0, bitmap_data.bmWidth, bitmap_data.bmHeight); |
| 105 clip_region_ = SkRegion(rect); | 108 clip_region_ = SkRegion(rect); |
| 106 } | 109 } |
| 107 | 110 |
| 108 transform_.reset(); | 111 transform_.reset(); |
| 109 } | 112 } |
| 110 | 113 |
| 111 BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData::~BitmapPlatformDeviceWinDa
ta() { | 114 BitmapPlatformDevice::BitmapPlatformDeviceData::~BitmapPlatformDeviceData() { |
| 112 if (hdc_) | 115 if (hdc_) |
| 113 ReleaseBitmapDC(); | 116 ReleaseBitmapDC(); |
| 114 | 117 |
| 115 // this will free the bitmap data as well as the bitmap handle | 118 // this will free the bitmap data as well as the bitmap handle |
| 116 DeleteObject(hbitmap_); | 119 DeleteObject(hbitmap_); |
| 117 } | 120 } |
| 118 | 121 |
| 119 HDC BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData::GetBitmapDC() { | 122 HDC BitmapPlatformDevice::BitmapPlatformDeviceData::GetBitmapDC() { |
| 120 if (!hdc_) { | 123 if (!hdc_) { |
| 121 hdc_ = CreateCompatibleDC(NULL); | 124 hdc_ = CreateCompatibleDC(NULL); |
| 122 InitializeDC(hdc_); | 125 InitializeDC(hdc_); |
| 123 HGDIOBJ old_bitmap = SelectObject(hdc_, hbitmap_); | 126 HGDIOBJ old_bitmap = SelectObject(hdc_, hbitmap_); |
| 124 // When the memory DC is created, its display surface is exactly one | 127 // When the memory DC is created, its display surface is exactly one |
| 125 // monochrome pixel wide and one monochrome pixel high. Since we select our | 128 // monochrome pixel wide and one monochrome pixel high. Since we select our |
| 126 // own bitmap, we must delete the previous one. | 129 // own bitmap, we must delete the previous one. |
| 127 DeleteObject(old_bitmap); | 130 DeleteObject(old_bitmap); |
| 128 } | 131 } |
| 129 | 132 |
| 130 LoadConfig(); | 133 LoadConfig(); |
| 131 return hdc_; | 134 return hdc_; |
| 132 } | 135 } |
| 133 | 136 |
| 134 void BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData::ReleaseBitmapDC() { | 137 void BitmapPlatformDevice::BitmapPlatformDeviceData::ReleaseBitmapDC() { |
| 135 SkASSERT(hdc_); | 138 SkASSERT(hdc_); |
| 136 DeleteDC(hdc_); | 139 DeleteDC(hdc_); |
| 137 hdc_ = NULL; | 140 hdc_ = NULL; |
| 138 } | 141 } |
| 139 | 142 |
| 140 bool BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData::IsBitmapDCCreated() | 143 bool BitmapPlatformDevice::BitmapPlatformDeviceData::IsBitmapDCCreated() |
| 141 const { | 144 const { |
| 142 return hdc_ != NULL; | 145 return hdc_ != NULL; |
| 143 } | 146 } |
| 144 | 147 |
| 145 | 148 |
| 146 void BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData::SetMatrixClip( | 149 void BitmapPlatformDevice::BitmapPlatformDeviceData::SetMatrixClip( |
| 147 const SkMatrix& transform, | 150 const SkMatrix& transform, |
| 148 const SkRegion& region) { | 151 const SkRegion& region) { |
| 149 transform_ = transform; | 152 transform_ = transform; |
| 150 clip_region_ = region; | 153 clip_region_ = region; |
| 151 config_dirty_ = true; | 154 config_dirty_ = true; |
| 152 } | 155 } |
| 153 | 156 |
| 154 void BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData::LoadConfig() { | 157 void BitmapPlatformDevice::BitmapPlatformDeviceData::LoadConfig() { |
| 155 if (!config_dirty_ || !hdc_) | 158 if (!config_dirty_ || !hdc_) |
| 156 return; // Nothing to do. | 159 return; // Nothing to do. |
| 157 config_dirty_ = false; | 160 config_dirty_ = false; |
| 158 | 161 |
| 159 // Transform. | 162 // Transform. |
| 160 SkMatrix t(transform_); | 163 SkMatrix t(transform_); |
| 161 LoadTransformToDC(hdc_, t); | 164 LoadTransformToDC(hdc_, t); |
| 162 LoadClippingRegionToDC(hdc_, clip_region_, t); | 165 LoadClippingRegionToDC(hdc_, clip_region_, t); |
| 163 } | 166 } |
| 164 | 167 |
| 165 // We use this static factory function instead of the regular constructor so | 168 // We use this static factory function instead of the regular constructor so |
| 166 // that we can create the pixel data before calling the constructor. This is | 169 // that we can create the pixel data before calling the constructor. This is |
| 167 // required so that we can call the base class' constructor with the pixel | 170 // required so that we can call the base class' constructor with the pixel |
| 168 // data. | 171 // data. |
| 169 BitmapPlatformDeviceWin* BitmapPlatformDeviceWin::create( | 172 BitmapPlatformDevice* BitmapPlatformDevice::create( |
| 170 HDC screen_dc, | 173 HDC screen_dc, |
| 171 int width, | 174 int width, |
| 172 int height, | 175 int height, |
| 173 bool is_opaque, | 176 bool is_opaque, |
| 174 HANDLE shared_section) { | 177 HANDLE shared_section) { |
| 175 SkBitmap bitmap; | 178 SkBitmap bitmap; |
| 176 | 179 |
| 177 // CreateDIBSection appears to get unhappy if we create an empty bitmap, so | 180 // CreateDIBSection appears to get unhappy if we create an empty bitmap, so |
| 178 // just create a minimal bitmap | 181 // just create a minimal bitmap |
| 179 if ((width == 0) || (height == 0)) { | 182 if ((width == 0) || (height == 0)) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 // To aid in finding bugs, we set the background color to something | 215 // To aid in finding bugs, we set the background color to something |
| 213 // obviously wrong so it will be noticable when it is not cleared | 216 // obviously wrong so it will be noticable when it is not cleared |
| 214 bitmap.eraseARGB(255, 0, 255, 128); // bright bluish green | 217 bitmap.eraseARGB(255, 0, 255, 128); // bright bluish green |
| 215 #endif | 218 #endif |
| 216 } else { | 219 } else { |
| 217 bitmap.eraseARGB(0, 0, 0, 0); | 220 bitmap.eraseARGB(0, 0, 0, 0); |
| 218 } | 221 } |
| 219 | 222 |
| 220 // The device object will take ownership of the HBITMAP. The initial refcount | 223 // The device object will take ownership of the HBITMAP. The initial refcount |
| 221 // of the data object will be 1, which is what the constructor expects. | 224 // of the data object will be 1, which is what the constructor expects. |
| 222 return new BitmapPlatformDeviceWin(new BitmapPlatformDeviceWinData(hbitmap), | 225 return new BitmapPlatformDevice(new BitmapPlatformDeviceData(hbitmap), |
| 223 bitmap); | 226 bitmap); |
| 227 } |
| 228 |
| 229 // static |
| 230 BitmapPlatformDevice* BitmapPlatformDevice::create(int width, |
| 231 int height, |
| 232 bool is_opaque, |
| 233 HANDLE shared_section) { |
| 234 HDC screen_dc = GetDC(NULL); |
| 235 BitmapPlatformDevice* device = BitmapPlatformDevice::create( |
| 236 screen_dc, width, height, is_opaque, shared_section); |
| 237 ReleaseDC(NULL, screen_dc); |
| 238 return device; |
| 224 } | 239 } |
| 225 | 240 |
| 226 // The device will own the HBITMAP, which corresponds to also owning the pixel | 241 // The device will own the HBITMAP, which corresponds to also owning the pixel |
| 227 // data. Therefore, we do not transfer ownership to the SkDevice's bitmap. | 242 // data. Therefore, we do not transfer ownership to the SkDevice's bitmap. |
| 228 BitmapPlatformDeviceWin::BitmapPlatformDeviceWin( | 243 BitmapPlatformDevice::BitmapPlatformDevice( |
| 229 BitmapPlatformDeviceWinData* data, | 244 BitmapPlatformDeviceData* data, |
| 230 const SkBitmap& bitmap) | 245 const SkBitmap& bitmap) |
| 231 : PlatformDeviceWin(bitmap), | 246 : PlatformDevice(bitmap), |
| 232 data_(data) { | 247 data_(data) { |
| 233 // The data object is already ref'ed for us by create(). | 248 // The data object is already ref'ed for us by create(). |
| 234 } | 249 } |
| 235 | 250 |
| 236 // The copy constructor just adds another reference to the underlying data. | 251 // The copy constructor just adds another reference to the underlying data. |
| 237 // We use a const cast since the default Skia definitions don't define the | 252 // We use a const cast since the default Skia definitions don't define the |
| 238 // proper constedness that we expect (accessBitmap should really be const). | 253 // proper constedness that we expect (accessBitmap should really be const). |
| 239 BitmapPlatformDeviceWin::BitmapPlatformDeviceWin( | 254 BitmapPlatformDevice::BitmapPlatformDevice( |
| 240 const BitmapPlatformDeviceWin& other) | 255 const BitmapPlatformDevice& other) |
| 241 : PlatformDeviceWin( | 256 : PlatformDevice( |
| 242 const_cast<BitmapPlatformDeviceWin&>(other).accessBitmap(true)), | 257 const_cast<BitmapPlatformDevice&>(other).accessBitmap(true)), |
| 243 data_(other.data_) { | 258 data_(other.data_) { |
| 244 data_->ref(); | 259 data_->ref(); |
| 245 } | 260 } |
| 246 | 261 |
| 247 BitmapPlatformDeviceWin::~BitmapPlatformDeviceWin() { | 262 BitmapPlatformDevice::~BitmapPlatformDevice() { |
| 248 data_->unref(); | 263 data_->unref(); |
| 249 } | 264 } |
| 250 | 265 |
| 251 BitmapPlatformDeviceWin& BitmapPlatformDeviceWin::operator=( | 266 BitmapPlatformDevice& BitmapPlatformDevice::operator=( |
| 252 const BitmapPlatformDeviceWin& other) { | 267 const BitmapPlatformDevice& other) { |
| 253 data_ = other.data_; | 268 data_ = other.data_; |
| 254 data_->ref(); | 269 data_->ref(); |
| 255 return *this; | 270 return *this; |
| 256 } | 271 } |
| 257 | 272 |
| 258 HDC BitmapPlatformDeviceWin::getBitmapDC() { | 273 HDC BitmapPlatformDevice::getBitmapDC() { |
| 259 return data_->GetBitmapDC(); | 274 return data_->GetBitmapDC(); |
| 260 } | 275 } |
| 261 | 276 |
| 262 void BitmapPlatformDeviceWin::setMatrixClip(const SkMatrix& transform, | 277 void BitmapPlatformDevice::setMatrixClip(const SkMatrix& transform, |
| 263 const SkRegion& region) { | 278 const SkRegion& region) { |
| 264 data_->SetMatrixClip(transform, region); | 279 data_->SetMatrixClip(transform, region); |
| 265 } | 280 } |
| 266 | 281 |
| 267 void BitmapPlatformDeviceWin::drawToHDC(HDC dc, int x, int y, | 282 void BitmapPlatformDevice::drawToHDC(HDC dc, int x, int y, |
| 268 const RECT* src_rect) { | 283 const RECT* src_rect) { |
| 269 bool created_dc = !data_->IsBitmapDCCreated(); | 284 bool created_dc = !data_->IsBitmapDCCreated(); |
| 270 HDC source_dc = getBitmapDC(); | 285 HDC source_dc = getBitmapDC(); |
| 271 | 286 |
| 272 RECT temp_rect; | 287 RECT temp_rect; |
| 273 if (!src_rect) { | 288 if (!src_rect) { |
| 274 temp_rect.left = 0; | 289 temp_rect.left = 0; |
| 275 temp_rect.right = width(); | 290 temp_rect.right = width(); |
| 276 temp_rect.top = 0; | 291 temp_rect.top = 0; |
| 277 temp_rect.bottom = height(); | 292 temp_rect.bottom = height(); |
| 278 src_rect = &temp_rect; | 293 src_rect = &temp_rect; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 311 copy_width, | 326 copy_width, |
| 312 copy_height, | 327 copy_height, |
| 313 blend_function); | 328 blend_function); |
| 314 } | 329 } |
| 315 LoadTransformToDC(source_dc, data_->transform()); | 330 LoadTransformToDC(source_dc, data_->transform()); |
| 316 | 331 |
| 317 if (created_dc) | 332 if (created_dc) |
| 318 data_->ReleaseBitmapDC(); | 333 data_->ReleaseBitmapDC(); |
| 319 } | 334 } |
| 320 | 335 |
| 321 void BitmapPlatformDeviceWin::makeOpaque(int x, int y, int width, int height) { | 336 void BitmapPlatformDevice::makeOpaque(int x, int y, int width, int height) { |
| 322 const SkBitmap& bitmap = accessBitmap(true); | 337 const SkBitmap& bitmap = accessBitmap(true); |
| 323 SkASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config); | 338 SkASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config); |
| 324 | 339 |
| 325 // FIXME(brettw): This is kind of lame, we shouldn't be dealing with | 340 // FIXME(brettw): This is kind of lame, we shouldn't be dealing with |
| 326 // transforms at this level. Probably there should be a PlatformCanvas | 341 // transforms at this level. Probably there should be a PlatformCanvas |
| 327 // function that does the transform (using the actual transform not just the | 342 // function that does the transform (using the actual transform not just the |
| 328 // translation) and calls us with the transformed rect. | 343 // translation) and calls us with the transformed rect. |
| 329 const SkMatrix& matrix = data_->transform(); | 344 const SkMatrix& matrix = data_->transform(); |
| 330 int bitmap_start_x = SkScalarRound(matrix.getTranslateX()) + x; | 345 int bitmap_start_x = SkScalarRound(matrix.getTranslateX()) + x; |
| 331 int bitmap_start_y = SkScalarRound(matrix.getTranslateY()) + y; | 346 int bitmap_start_y = SkScalarRound(matrix.getTranslateY()) + y; |
| 332 | 347 |
| 333 if (Constrain(bitmap.width(), &bitmap_start_x, &width) && | 348 if (Constrain(bitmap.width(), &bitmap_start_x, &width) && |
| 334 Constrain(bitmap.height(), &bitmap_start_y, &height)) { | 349 Constrain(bitmap.height(), &bitmap_start_y, &height)) { |
| 335 SkAutoLockPixels lock(bitmap); | 350 SkAutoLockPixels lock(bitmap); |
| 336 SkASSERT(bitmap.rowBytes() % sizeof(uint32_t) == 0u); | 351 SkASSERT(bitmap.rowBytes() % sizeof(uint32_t) == 0u); |
| 337 size_t row_words = bitmap.rowBytes() / sizeof(uint32_t); | 352 size_t row_words = bitmap.rowBytes() / sizeof(uint32_t); |
| 338 // Set data to the first pixel to be modified. | 353 // Set data to the first pixel to be modified. |
| 339 uint32_t* data = bitmap.getAddr32(0, 0) + (bitmap_start_y * row_words) + | 354 uint32_t* data = bitmap.getAddr32(0, 0) + (bitmap_start_y * row_words) + |
| 340 bitmap_start_x; | 355 bitmap_start_x; |
| 341 for (int i = 0; i < height; i++) { | 356 for (int i = 0; i < height; i++) { |
| 342 for (int j = 0; j < width; j++) | 357 for (int j = 0; j < width; j++) |
| 343 data[j] |= (0xFF << SK_A32_SHIFT); | 358 data[j] |= (0xFF << SK_A32_SHIFT); |
| 344 data += row_words; | 359 data += row_words; |
| 345 } | 360 } |
| 346 } | 361 } |
| 347 } | 362 } |
| 348 | 363 |
| 349 // Returns the color value at the specified location. | 364 // Returns the color value at the specified location. |
| 350 SkColor BitmapPlatformDeviceWin::getColorAt(int x, int y) { | 365 SkColor BitmapPlatformDevice::getColorAt(int x, int y) { |
| 351 const SkBitmap& bitmap = accessBitmap(false); | 366 const SkBitmap& bitmap = accessBitmap(false); |
| 352 SkAutoLockPixels lock(bitmap); | 367 SkAutoLockPixels lock(bitmap); |
| 353 uint32_t* data = bitmap.getAddr32(0, 0); | 368 uint32_t* data = bitmap.getAddr32(0, 0); |
| 354 return static_cast<SkColor>(data[x + y * width()]); | 369 return static_cast<SkColor>(data[x + y * width()]); |
| 355 } | 370 } |
| 356 | 371 |
| 357 void BitmapPlatformDeviceWin::onAccessBitmap(SkBitmap* bitmap) { | 372 void BitmapPlatformDevice::onAccessBitmap(SkBitmap* bitmap) { |
| 358 // FIXME(brettw) OPTIMIZATION: We should only flush if we know a GDI | 373 // FIXME(brettw) OPTIMIZATION: We should only flush if we know a GDI |
| 359 // operation has occurred on our DC. | 374 // operation has occurred on our DC. |
| 360 if (data_->IsBitmapDCCreated()) | 375 if (data_->IsBitmapDCCreated()) |
| 361 GdiFlush(); | 376 GdiFlush(); |
| 362 } | 377 } |
| 363 | 378 |
| 364 } // namespace skia | 379 } // namespace skia |
| 365 | 380 |
| OLD | NEW |