| 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 "base/gfx/bitmap_platform_device_win.h" | 5 #include "base/gfx/bitmap_platform_device_win.h" |
| 6 | 6 |
| 7 #include "base/gfx/gdi_util.h" | 7 #include "base/gfx/gdi_util.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/process_util.h" | |
| 10 #include "SkMatrix.h" | 9 #include "SkMatrix.h" |
| 11 #include "SkRegion.h" | 10 #include "SkRegion.h" |
| 12 #include "SkUtils.h" | 11 #include "SkUtils.h" |
| 13 | 12 |
| 14 namespace gfx { | 13 namespace gfx { |
| 15 | 14 |
| 16 // When Windows draws text, is sets the fourth byte (which Skia uses for alpha) | 15 // When Windows draws text, is sets the fourth byte (which Skia uses for alpha) |
| 17 // to zero. This means that if we try compositing with text that Windows has | 16 // to zero. This means that if we try compositing with text that Windows has |
| 18 // drawn, we get invalid color values (if the alpha is 0, the other channels | 17 // drawn, we get invalid color values (if the alpha is 0, the other channels |
| 19 // should be 0 since Skia uses premultiplied colors) and strange results. | 18 // should be 0 since Skia uses premultiplied colors) and strange results. |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 } | 91 } |
| 93 | 92 |
| 94 // See the declaration of kMagicTransparencyColor at the top of the file. | 93 // See the declaration of kMagicTransparencyColor at the top of the file. |
| 95 void FixupAlphaBeforeCompositing(uint32_t* pixel) { | 94 void FixupAlphaBeforeCompositing(uint32_t* pixel) { |
| 96 if (*pixel == kMagicTransparencyColor) | 95 if (*pixel == kMagicTransparencyColor) |
| 97 *pixel = 0; | 96 *pixel = 0; |
| 98 else | 97 else |
| 99 *pixel |= 0xFF000000; | 98 *pixel |= 0xFF000000; |
| 100 } | 99 } |
| 101 | 100 |
| 102 // Crashes the process. This is called when a bitmap allocation fails, and this | |
| 103 // function tries to determine why it might have failed, and crash on different | |
| 104 // lines. This allows us to see in crash dumps the most likely reason for the | |
| 105 // failure. It takes the size of the bitmap we were trying to allocate as its | |
| 106 // arguments so we can check that as well. | |
| 107 void CrashForBitmapAllocationFailure(int w, int h) { | |
| 108 // The maximum number of GDI objects per process is 10K. If we're very close | |
| 109 // to that, it's probably the problem. | |
| 110 const int kLotsOfGDIObjs = 9990; | |
| 111 CHECK(GetGuiResources(GetCurrentProcess(), GR_GDIOBJECTS) < kLotsOfGDIObjs); | |
| 112 | |
| 113 // If the bitmap is ginormous, then we probably can't allocate it. | |
| 114 // We use 64M pixels = 256MB @ 4 bytes per pixel. | |
| 115 const int64 kGinormousBitmapPxl = 64000000; | |
| 116 CHECK(static_cast<int64>(w) * static_cast<int64>(h) < kGinormousBitmapPxl); | |
| 117 | |
| 118 // If we're using a crazy amount of virtual address space, then maybe there | |
| 119 // isn't enough for our bitmap. | |
| 120 const int64 kLotsOfMem = 1500000000; // 1.5GB. | |
| 121 scoped_ptr<process_util::ProcessMetrics> process_metrics( | |
| 122 process_util::ProcessMetrics::CreateProcessMetrics(GetCurrentProcess())); | |
| 123 CHECK(process_metrics->GetPagefileUsage() < kLotsOfMem); | |
| 124 | |
| 125 // Everything else. | |
| 126 CHECK(0); | |
| 127 } | |
| 128 | |
| 129 } // namespace | 101 } // namespace |
| 130 | 102 |
| 131 class BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData | 103 class BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData |
| 132 : public base::RefCounted<BitmapPlatformDeviceWinData> { | 104 : public base::RefCounted<BitmapPlatformDeviceWinData> { |
| 133 public: | 105 public: |
| 134 explicit BitmapPlatformDeviceWinData(HBITMAP hbitmap); | 106 explicit BitmapPlatformDeviceWinData(HBITMAP hbitmap); |
| 135 | 107 |
| 136 // Create/destroy hdc_, which is the memory DC for our bitmap data. | 108 // Create/destroy hdc_, which is the memory DC for our bitmap data. |
| 137 HDC GetBitmapDC(); | 109 HDC GetBitmapDC(); |
| 138 void ReleaseBitmapDC(); | 110 void ReleaseBitmapDC(); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 256 // required so that we can call the base class' constructor with the pixel | 228 // required so that we can call the base class' constructor with the pixel |
| 257 // data. | 229 // data. |
| 258 BitmapPlatformDeviceWin* BitmapPlatformDeviceWin::create(HDC screen_dc, | 230 BitmapPlatformDeviceWin* BitmapPlatformDeviceWin::create(HDC screen_dc, |
| 259 int width, | 231 int width, |
| 260 int height, | 232 int height, |
| 261 bool is_opaque, | 233 bool is_opaque, |
| 262 HANDLE shared_section) { | 234 HANDLE shared_section) { |
| 263 SkBitmap bitmap; | 235 SkBitmap bitmap; |
| 264 | 236 |
| 265 // CreateDIBSection appears to get unhappy if we create an empty bitmap, so | 237 // CreateDIBSection appears to get unhappy if we create an empty bitmap, so |
| 266 // we just expand it here. | 238 // just create a minimal bitmap |
| 267 if (width == 0) | 239 if ((width == 0) || (height == 0)) { |
| 268 width = 1; | 240 width = 1; |
| 269 if (height == 0) | |
| 270 height = 1; | 241 height = 1; |
| 242 } |
| 271 | 243 |
| 272 BITMAPINFOHEADER hdr; | 244 BITMAPINFOHEADER hdr = {0}; |
| 273 CreateBitmapHeader(width, height, &hdr); | 245 CreateBitmapHeader(width, height, &hdr); |
| 274 | 246 |
| 275 void* data; | 247 void* data = NULL; |
| 276 HBITMAP hbitmap = CreateDIBSection(screen_dc, | 248 HBITMAP hbitmap = CreateDIBSection(screen_dc, |
| 277 reinterpret_cast<BITMAPINFO*>(&hdr), 0, | 249 reinterpret_cast<BITMAPINFO*>(&hdr), 0, |
| 278 &data, | 250 &data, |
| 279 shared_section, 0); | 251 shared_section, 0); |
| 280 | 252 |
| 281 // If we run out of GDI objects or some other error occurs, we won't get a | 253 // If we run out of GDI objects or some other error occurs, we won't get a |
| 282 // bitmap here. This will cause us to crash later because the data pointer is | 254 // bitmap here. This will cause us to crash later because the data pointer is |
| 283 // NULL. To make sure that we can assign blame for those crashes to this code, | 255 // NULL. To make sure that we can assign blame for those crashes to this code, |
| 284 // we deliberately crash here, even in release mode. | 256 // we deliberately crash here, even in release mode. |
| 285 if (!hbitmap) | 257 if (!hbitmap) { |
| 286 CrashForBitmapAllocationFailure(width, height); | 258 DWORD error = GetLastError(); |
| 259 NOTREACHED() << "CreateDIBSection Failed. Error: " << error << "\n"; |
| 260 return NULL; |
| 261 } |
| 287 | 262 |
| 288 bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height); | 263 bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height); |
| 289 bitmap.setPixels(data); | 264 bitmap.setPixels(data); |
| 290 bitmap.setIsOpaque(is_opaque); | 265 bitmap.setIsOpaque(is_opaque); |
| 291 | 266 |
| 292 if (is_opaque) { | 267 if (is_opaque) { |
| 293 #ifndef NDEBUG | 268 #ifndef NDEBUG |
| 294 // To aid in finding bugs, we set the background color to something | 269 // To aid in finding bugs, we set the background color to something |
| 295 // obviously wrong so it will be noticable when it is not cleared | 270 // obviously wrong so it will be noticable when it is not cleared |
| 296 bitmap.eraseARGB(255, 0, 255, 128); // bright bluish green | 271 bitmap.eraseARGB(255, 0, 255, 128); // bright bluish green |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 for (int j = 0; j < width; j++) { | 437 for (int j = 0; j < width; j++) { |
| 463 adjustor(data + j); | 438 adjustor(data + j); |
| 464 } | 439 } |
| 465 data += row_words; | 440 data += row_words; |
| 466 } | 441 } |
| 467 } | 442 } |
| 468 } | 443 } |
| 469 | 444 |
| 470 } // namespace gfx | 445 } // namespace gfx |
| 471 | 446 |
| OLD | NEW |