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

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

Issue 2365903002: Fix GDI leak in NativeThemeWin::PaintIndirect (Closed)
Patch Set: fix comment 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 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 double ratio = fmod(animated_seconds, interval) / interval; 105 double ratio = fmod(animated_seconds, interval) / interval;
105 return static_cast<int>(animation_width * ratio) - object_width; 106 return static_cast<int>(animation_width * ratio) - object_width;
106 } 107 }
107 108
108 RECT InsetRect(const RECT* rect, int size) { 109 RECT InsetRect(const RECT* rect, int size) {
109 gfx::Rect result(*rect); 110 gfx::Rect result(*rect);
110 result.Inset(size, size); 111 result.Inset(size, size);
111 return result.ToRECT(); 112 return result.ToRECT();
112 } 113 }
113 114
115 // Custom scoped object for storing DC and a bitmap that was selected into it,
116 // and making sure that they are deleted in the right order.
117 class ScopedCreateDCWithBitmap {
118 public:
119 explicit ScopedCreateDCWithBitmap(base::win::ScopedCreateDC::Handle hdc)
120 : dc_(hdc) {}
121
122 ~ScopedCreateDCWithBitmap() {
123 // Delete DC before the bitmap, since objects should not be deleted while
124 // selected into a DC.
125 dc_.Close();
126 }
127
128 bool IsValid() const { return dc_.IsValid(); }
129
130 base::win::ScopedCreateDC::Handle Get() const { return dc_.Get(); }
131
132 // Selects |handle| to bitmap into DC. Returns false if handle is not valid.
133 bool SelectBitmap(base::win::ScopedBitmap::element_type handle) {
134 bitmap_.reset(handle);
135 if (!bitmap_.is_valid())
136 return false;
137
138 SelectObject(dc_.Get(), bitmap_.get());
139 return true;
140 }
141
142 private:
143 base::win::ScopedCreateDC dc_;
144 base::win::ScopedBitmap bitmap_;
145
146 DISALLOW_COPY_AND_ASSIGN(ScopedCreateDCWithBitmap);
147 };
148
114 } // namespace 149 } // namespace
115 150
116 namespace ui { 151 namespace ui {
117 152
118 bool NativeThemeWin::IsThemingActive() const { 153 bool NativeThemeWin::IsThemingActive() const {
119 return is_theme_active_ && is_theme_active_(); 154 return is_theme_active_ && is_theme_active_();
120 } 155 }
121 156
122 bool NativeThemeWin::IsUsingHighContrastTheme() const { 157 bool NativeThemeWin::IsUsingHighContrastTheme() const {
123 if (is_using_high_contrast_valid_) 158 if (is_using_high_contrast_valid_)
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 HDC destination_hdc, 692 HDC destination_hdc,
658 Part part, 693 Part part,
659 State state, 694 State state,
660 const gfx::Rect& rect, 695 const gfx::Rect& rect,
661 const ExtraParams& extra) const { 696 const ExtraParams& extra) const {
662 // TODO(asvitkine): This path is pretty inefficient - for each paint operation 697 // TODO(asvitkine): This path is pretty inefficient - for each paint operation
663 // it creates a new offscreen bitmap Skia canvas. This can 698 // it creates a new offscreen bitmap Skia canvas. This can
664 // be sped up by doing it only once per part/state and 699 // be sped up by doing it only once per part/state and
665 // keeping a cache of the resulting bitmaps. 700 // keeping a cache of the resulting bitmaps.
666 701
667 // Create an offscreen canvas that is backed by an HDC. 702 // If this process doesn't have access to GDI, we'd need to use shared memory
668 // This can fail if we don't have access to GDI or if lower-level Windows 703 // segment instead but that is not supported right now.
669 // calls fail, possibly due to GDI handle exhaustion. 704 if (!base::win::IsUser32AndGdi32Available())
670 base::win::ScopedCreateDC offscreen_hdc( 705 return;
671 skia::CreateOffscreenSurface(rect.width(), rect.height())); 706
707 ScopedCreateDCWithBitmap offscreen_hdc(CreateCompatibleDC(nullptr));
672 if (!offscreen_hdc.IsValid()) 708 if (!offscreen_hdc.IsValid())
673 return; 709 return;
674 710
711 skia::InitializeDC(offscreen_hdc.Get());
712 HRGN clip = CreateRectRgn(0, 0, rect.width(), rect.height());
713 if ((SelectClipRgn(offscreen_hdc.Get(), clip) == ERROR) ||
714 !DeleteObject(clip)) {
Peter Kasting 2016/09/26 20:58:33 Nit: {} not necessary (2 places)
Rafał Chłodnicki 2016/09/27 07:00:48 I much prefer when there are braces when condition
Peter Kasting 2016/09/27 07:05:40 It was never part of the style guide -- in fact we
715 return;
716 }
717
718 if (!offscreen_hdc.SelectBitmap(skia::CreateHBitmap(
719 rect.width(), rect.height(), false, nullptr, nullptr))) {
720 return;
721 }
722
675 // Will be NULL if lower-level Windows calls fail, or if the backing 723 // 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 724 // allocated is 0 pixels in size (which should never happen according to
677 // Windows documentation). 725 // Windows documentation).
678 sk_sp<SkSurface> offscreen_surface = 726 sk_sp<SkSurface> offscreen_surface =
679 skia::MapPlatformSurface(offscreen_hdc.Get()); 727 skia::MapPlatformSurface(offscreen_hdc.Get());
680 if (!offscreen_surface) 728 if (!offscreen_surface)
681 return; 729 return;
682 730
683 SkCanvas* offscreen_canvas = offscreen_surface->getCanvas(); 731 SkCanvas* offscreen_canvas = offscreen_surface->getCanvas();
684 DCHECK(offscreen_canvas); 732 DCHECK(offscreen_canvas);
(...skipping 1387 matching lines...) Expand 10 before | Expand all | Expand 10 after
2072 break; 2120 break;
2073 case LAST: 2121 case LAST:
2074 NOTREACHED(); 2122 NOTREACHED();
2075 break; 2123 break;
2076 } 2124 }
2077 theme_handles_[theme_name] = handle; 2125 theme_handles_[theme_name] = handle;
2078 return handle; 2126 return handle;
2079 } 2127 }
2080 2128
2081 } // namespace ui 2129 } // 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