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

Side by Side Diff: ui/native_theme/native_theme_win.cc

Issue 2365903002: Fix GDI leak in NativeThemeWin::PaintIndirect (Closed)
Patch Set: was totally untested before this patch Created 4 years, 2 months 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
« no previous file with comments | « skia/ext/skia_utils_win.cc ('k') | no next file » | 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "ui/native_theme/native_theme_win.h" 5 #include "ui/native_theme/native_theme_win.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <uxtheme.h> 9 #include <uxtheme.h>
10 #include <vsstyle.h> 10 #include <vsstyle.h>
11 #include <vssym32.h> 11 #include <vssym32.h>
12 12
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/macros.h" 14 #include "base/macros.h"
15 #include "base/win/scoped_gdi_object.h" 15 #include "base/win/scoped_gdi_object.h"
16 #include "base/win/scoped_hdc.h" 16 #include "base/win/scoped_hdc.h"
17 #include "base/win/scoped_select_object.h" 17 #include "base/win/scoped_select_object.h"
18 #include "base/win/win_util.h"
18 #include "base/win/windows_version.h" 19 #include "base/win/windows_version.h"
19 #include "skia/ext/bitmap_platform_device.h" 20 #include "skia/ext/bitmap_platform_device.h"
20 #include "skia/ext/platform_canvas.h" 21 #include "skia/ext/platform_canvas.h"
21 #include "skia/ext/skia_utils_win.h" 22 #include "skia/ext/skia_utils_win.h"
22 #include "third_party/skia/include/core/SkCanvas.h" 23 #include "third_party/skia/include/core/SkCanvas.h"
23 #include "third_party/skia/include/core/SkColor.h" 24 #include "third_party/skia/include/core/SkColor.h"
24 #include "third_party/skia/include/core/SkColorPriv.h" 25 #include "third_party/skia/include/core/SkColorPriv.h"
25 #include "third_party/skia/include/core/SkPath.h" 26 #include "third_party/skia/include/core/SkPath.h"
26 #include "third_party/skia/include/core/SkRefCnt.h" 27 #include "third_party/skia/include/core/SkRefCnt.h"
27 #include "third_party/skia/include/core/SkShader.h" 28 #include "third_party/skia/include/core/SkShader.h"
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 State state, 660 State state,
660 const gfx::Rect& rect, 661 const gfx::Rect& rect,
661 const ExtraParams& extra) const { 662 const ExtraParams& extra) const {
662 // TODO(asvitkine): This path is pretty inefficient - for each paint operation 663 // TODO(asvitkine): This path is pretty inefficient - for each paint operation
663 // it creates a new offscreen bitmap Skia canvas. This can 664 // it creates a new offscreen bitmap Skia canvas. This can
664 // be sped up by doing it only once per part/state and 665 // be sped up by doing it only once per part/state and
665 // keeping a cache of the resulting bitmaps. 666 // keeping a cache of the resulting bitmaps.
666 667
667 // Create an offscreen canvas that is backed by an HDC. 668 // Create an offscreen canvas that is backed by an HDC.
668 // This can fail if we don't have access to GDI or if lower-level Windows 669 // This can fail if we don't have access to GDI or if lower-level Windows
669 // calls fail, possibly due to GDI handle exhaustion. 670 // calls fail, possibly due to GDI handle exhaustion.
Peter Kasting 2016/09/24 00:52:34 Nit: This comment is now a bit redundant with some
Rafał Chłodnicki 2016/09/26 10:12:09 Done.
670 base::win::ScopedCreateDC offscreen_hdc( 671
671 skia::CreateOffscreenSurface(rect.width(), rect.height())); 672 // If this process doesn't have access to GDI, we'd need to use shared memory
673 // segment instead but that is not supported right now.
674 if (!base::win::IsUser32AndGdi32Available())
675 return;
676
677 base::win::ScopedCreateDC offscreen_hdc(CreateCompatibleDC(nullptr));
672 if (!offscreen_hdc.IsValid()) 678 if (!offscreen_hdc.IsValid())
673 return; 679 return;
674 680
681 skia::InitializeDC(offscreen_hdc.Get());
682 HRGN clip = CreateRectRgn(0, 0, rect.width(), rect.height());
683 if ((SelectClipRgn(offscreen_hdc.Get(), clip) == ERROR) ||
684 !DeleteObject(clip)) {
685 return;
686 }
687
688 base::win::ScopedBitmap hdc_bitmap(skia::CreateHBitmap(
Peter Kasting 2016/09/24 00:52:34 I would avoid using ScopedBitmap directly here. W
Rafał Chłodnicki 2016/09/26 10:12:09 Done.
689 rect.width(), rect.height(), false, nullptr, nullptr));
690 if (!hdc_bitmap.is_valid())
691 return;
692
693 SelectObject(offscreen_hdc.Get(), hdc_bitmap.get());
694
675 // Will be NULL if lower-level Windows calls fail, or if the backing 695 // Will be NULL if lower-level Windows calls fail, or if the backing
676 // allocated is 0 pixels in size (which should never happen according to 696 // allocated is 0 pixels in size (which should never happen according to
677 // Windows documentation). 697 // Windows documentation).
678 sk_sp<SkSurface> offscreen_surface = 698 sk_sp<SkSurface> offscreen_surface =
679 skia::MapPlatformSurface(offscreen_hdc.Get()); 699 skia::MapPlatformSurface(offscreen_hdc.Get());
680 if (!offscreen_surface) 700 if (!offscreen_surface)
681 return; 701 return;
682 702
683 SkCanvas* offscreen_canvas = offscreen_surface->getCanvas(); 703 SkCanvas* offscreen_canvas = offscreen_surface->getCanvas();
684 DCHECK(offscreen_canvas); 704 DCHECK(offscreen_canvas);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 } else if (SkGetPackedA32(pixels[i]) == 0) { 746 } else if (SkGetPackedA32(pixels[i]) == 0) {
727 // Pixel was touched but has incorrect alpha of 0, make it fully opaque. 747 // Pixel was touched but has incorrect alpha of 0, make it fully opaque.
728 pixels[i] = SkPackARGB32(0xFF, 748 pixels[i] = SkPackARGB32(0xFF,
729 SkGetPackedR32(pixels[i]), 749 SkGetPackedR32(pixels[i]),
730 SkGetPackedG32(pixels[i]), 750 SkGetPackedG32(pixels[i]),
731 SkGetPackedB32(pixels[i])); 751 SkGetPackedB32(pixels[i]));
732 } 752 }
733 } 753 }
734 754
735 destination_canvas->drawBitmap(offscreen_bitmap, rect.x(), rect.y()); 755 destination_canvas->drawBitmap(offscreen_bitmap, rect.x(), rect.y());
756 // Delete hdc before bitmap.
Peter Kasting 2016/09/24 00:52:34 Nit: Blank line above this. Nit: I suggest adding
Rafał Chłodnicki 2016/09/26 10:12:09 Done.
757 offscreen_hdc.Close();
758 hdc_bitmap.reset();
Peter Kasting 2016/09/24 00:52:34 Nit: This statement unnecessary
Rafał Chłodnicki 2016/09/26 10:12:09 Done.
736 } 759 }
737 760
738 HRESULT NativeThemeWin::GetThemePartSize(ThemeName theme_name, 761 HRESULT NativeThemeWin::GetThemePartSize(ThemeName theme_name,
739 HDC hdc, 762 HDC hdc,
740 int part_id, 763 int part_id,
741 int state_id, 764 int state_id,
742 RECT* rect, 765 RECT* rect,
743 int ts, 766 int ts,
744 SIZE* size) const { 767 SIZE* size) const {
745 HANDLE handle = GetThemeHandle(theme_name); 768 HANDLE handle = GetThemeHandle(theme_name);
(...skipping 1326 matching lines...) Expand 10 before | Expand all | Expand 10 after
2072 break; 2095 break;
2073 case LAST: 2096 case LAST:
2074 NOTREACHED(); 2097 NOTREACHED();
2075 break; 2098 break;
2076 } 2099 }
2077 theme_handles_[theme_name] = handle; 2100 theme_handles_[theme_name] = handle;
2078 return handle; 2101 return handle;
2079 } 2102 }
2080 2103
2081 } // namespace ui 2104 } // namespace ui
OLDNEW
« no previous file with comments | « skia/ext/skia_utils_win.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698