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/platform_canvas_win.h" | 5 #include "base/gfx/platform_canvas_win.h" |
6 | 6 |
7 #include "base/gfx/bitmap_platform_device_win.h" | 7 #include "base/gfx/bitmap_platform_device_win.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/process_util.h" |
9 | 10 |
10 #ifdef ARCH_CPU_64_BITS | 11 #ifdef ARCH_CPU_64_BITS |
11 #error This code does not work on x64. Please make sure all the base unit tests\ | 12 #error This code does not work on x64. Please make sure all the base unit tests\ |
12 pass before doing any real work. | 13 pass before doing any real work. |
13 #endif | 14 #endif |
14 | 15 |
15 namespace gfx { | 16 namespace gfx { |
16 | 17 |
| 18 // Crashes the process. This is called when a bitmap allocation fails, and this |
| 19 // function tries to determine why it might have failed, and crash on different |
| 20 // lines. This allows us to see in crash dumps the most likely reason for the |
| 21 // failure. It takes the size of the bitmap we were trying to allocate as its |
| 22 // arguments so we can check that as well. |
| 23 void CrashForBitmapAllocationFailure(int w, int h) { |
| 24 // The maximum number of GDI objects per process is 10K. If we're very close |
| 25 // to that, it's probably the problem. |
| 26 const int kLotsOfGDIObjs = 9990; |
| 27 CHECK(GetGuiResources(GetCurrentProcess(), GR_GDIOBJECTS) < kLotsOfGDIObjs); |
| 28 |
| 29 // If the bitmap is ginormous, then we probably can't allocate it. |
| 30 // We use 64M pixels = 256MB @ 4 bytes per pixel. |
| 31 const int64 kGinormousBitmapPxl = 64000000; |
| 32 CHECK(static_cast<int64>(w) * static_cast<int64>(h) < kGinormousBitmapPxl); |
| 33 |
| 34 // If we're using a crazy amount of virtual address space, then maybe there |
| 35 // isn't enough for our bitmap. |
| 36 const int64 kLotsOfMem = 1500000000; // 1.5GB. |
| 37 scoped_ptr<process_util::ProcessMetrics> process_metrics( |
| 38 process_util::ProcessMetrics::CreateProcessMetrics(GetCurrentProcess())); |
| 39 CHECK(process_metrics->GetPagefileUsage() < kLotsOfMem); |
| 40 |
| 41 // Everything else. |
| 42 CHECK(0); |
| 43 } |
| 44 |
| 45 |
17 PlatformCanvasWin::PlatformCanvasWin() : SkCanvas() { | 46 PlatformCanvasWin::PlatformCanvasWin() : SkCanvas() { |
18 } | 47 } |
19 | 48 |
20 PlatformCanvasWin::PlatformCanvasWin(int width, int height, bool is_opaque) | 49 PlatformCanvasWin::PlatformCanvasWin(int width, int height, bool is_opaque) |
21 : SkCanvas() { | 50 : SkCanvas() { |
22 initialize(width, height, is_opaque, NULL); | 51 bool initialized = initialize(width, height, is_opaque, NULL); |
| 52 if (!initialized) |
| 53 CrashForBitmapAllocationFailure(width, height); |
23 } | 54 } |
24 | 55 |
25 PlatformCanvasWin::PlatformCanvasWin(int width, | 56 PlatformCanvasWin::PlatformCanvasWin(int width, |
26 int height, | 57 int height, |
27 bool is_opaque, | 58 bool is_opaque, |
28 HANDLE shared_section) | 59 HANDLE shared_section) |
29 : SkCanvas() { | 60 : SkCanvas() { |
30 initialize(width, height, is_opaque, shared_section); | 61 bool initialized = initialize(width, height, is_opaque, shared_section); |
| 62 if (!initialized) |
| 63 CrashForBitmapAllocationFailure(width, height); |
31 } | 64 } |
32 | 65 |
33 PlatformCanvasWin::~PlatformCanvasWin() { | 66 PlatformCanvasWin::~PlatformCanvasWin() { |
34 } | 67 } |
35 | 68 |
36 void PlatformCanvasWin::initialize(int width, | 69 bool PlatformCanvasWin::initialize(int width, |
37 int height, | 70 int height, |
38 bool is_opaque, | 71 bool is_opaque, |
39 HANDLE shared_section) { | 72 HANDLE shared_section) { |
40 SkDevice* device = | 73 SkDevice* device = |
41 createPlatformDevice(width, height, is_opaque, shared_section); | 74 createPlatformDevice(width, height, is_opaque, shared_section); |
| 75 if (!device) |
| 76 return false; |
| 77 |
42 setDevice(device); | 78 setDevice(device); |
43 device->unref(); // was created with refcount 1, and setDevice also refs | 79 device->unref(); // was created with refcount 1, and setDevice also refs |
| 80 return true; |
44 } | 81 } |
45 | 82 |
46 HDC PlatformCanvasWin::beginPlatformPaint() { | 83 HDC PlatformCanvasWin::beginPlatformPaint() { |
47 return getTopPlatformDevice().getBitmapDC(); | 84 return getTopPlatformDevice().getBitmapDC(); |
48 } | 85 } |
49 | 86 |
50 void PlatformCanvasWin::endPlatformPaint() { | 87 void PlatformCanvasWin::endPlatformPaint() { |
51 // we don't clear the DC here since it will be likely to be used again | 88 // we don't clear the DC here since it will be likely to be used again |
52 // flushing will be done in onAccessBitmap | 89 // flushing will be done in onAccessBitmap |
53 } | 90 } |
(...skipping 22 matching lines...) Expand all Loading... |
76 ReleaseDC(NULL, screen_dc); | 113 ReleaseDC(NULL, screen_dc); |
77 return device; | 114 return device; |
78 } | 115 } |
79 | 116 |
80 SkDevice* PlatformCanvasWin::setBitmapDevice(const SkBitmap&) { | 117 SkDevice* PlatformCanvasWin::setBitmapDevice(const SkBitmap&) { |
81 NOTREACHED(); | 118 NOTREACHED(); |
82 return NULL; | 119 return NULL; |
83 } | 120 } |
84 | 121 |
85 } // namespace gfx | 122 } // namespace gfx |
OLD | NEW |