Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(142)

Side by Side Diff: base/gfx/bitmap_platform_device_win.cc

Issue 9459: Make canvas code a bit more resilient to crashes.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | base/gfx/platform_canvas_win.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | base/gfx/platform_canvas_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698