OLD | NEW |
1 // Copyright (c) 2017 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2017 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 <windows.h> | 5 #include <windows.h> |
6 #include <psapi.h> | 6 #include <psapi.h> |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include "base/debug/gdi_debug_util_win.h" | 9 #include "base/debug/gdi_debug_util_win.h" |
10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/win/win_util.h" | 12 #include "base/win/win_util.h" |
13 #include "skia/ext/platform_canvas.h" | 13 #include "skia/ext/platform_canvas.h" |
14 #include "skia/ext/skia_utils_win.h" | 14 #include "skia/ext/skia_utils_win.h" |
15 #include "third_party/skia/include/core/SkMatrix.h" | 15 #include "third_party/skia/include/core/SkMatrix.h" |
16 #include "third_party/skia/include/core/SkPath.h" | 16 #include "third_party/skia/include/core/SkPath.h" |
17 #include "third_party/skia/include/core/SkRefCnt.h" | 17 #include "third_party/skia/include/core/SkRefCnt.h" |
18 #include "third_party/skia/include/core/SkRect.h" | 18 #include "third_party/skia/include/core/SkRect.h" |
19 | 19 |
20 namespace { | 20 namespace { |
21 | 21 |
| 22 struct HDCContextRec { |
| 23 HDC hdc_; |
| 24 HBITMAP prev_bitmap_; |
| 25 }; |
| 26 |
22 static void DeleteHDCCallback(void*, void* context) { | 27 static void DeleteHDCCallback(void*, void* context) { |
23 DCHECK_NE(context, nullptr); | 28 DCHECK_NE(context, nullptr); |
24 HDC hdc = static_cast<HDC>(context); | 29 const HDCContextRec* rec = static_cast<const HDCContextRec*>(context); |
25 | 30 |
26 // We must get this before we call RestoreDC, as that will drop hbitmap and | 31 // Must select back in the old bitmap before we delete the hdc, and so we can |
27 // reselect the original/default bitmap. | 32 // recover the new_bitmap that we allocated, so we can delete it. |
28 HGDIOBJ hbitmap = GetCurrentObject(hdc, OBJ_BITMAP); | 33 HBITMAP new_bitmap = |
29 DCHECK_NE(hbitmap, nullptr); | 34 static_cast<HBITMAP>(SelectObject(rec->hdc_, rec->prev_bitmap_)); |
30 | 35 bool success = DeleteObject(new_bitmap); |
31 bool success = RestoreDC(hdc, -1); // effectly performs the deselect of hbitma
p | |
32 DCHECK(success); | 36 DCHECK(success); |
33 | 37 success = DeleteDC(rec->hdc_); |
34 // Now we are the only owner, so we can delete our bitmap | |
35 success = DeleteObject(hbitmap); | |
36 DCHECK(success); | 38 DCHECK(success); |
37 success = DeleteDC(hdc); | 39 delete rec; |
38 DCHECK(success); | |
39 } | 40 } |
40 | 41 |
41 // Allocate the layer and fill in the fields for the Rec, or return false | 42 // Allocate the layer and fill in the fields for the Rec, or return false |
42 // on error. | 43 // on error. |
43 static bool Create(int width, | 44 static bool Create(int width, |
44 int height, | 45 int height, |
45 bool is_opaque, | 46 bool is_opaque, |
46 HANDLE shared_section, | 47 HANDLE shared_section, |
47 bool do_clear, | 48 bool do_clear, |
48 SkRasterHandleAllocator::Rec* rec) { | 49 SkRasterHandleAllocator::Rec* rec) { |
49 void* pixels; | 50 void* pixels; |
50 HBITMAP hbitmap = | 51 HBITMAP new_bitmap = |
51 skia::CreateHBitmap(width, height, is_opaque, shared_section, &pixels); | 52 skia::CreateHBitmap(width, height, is_opaque, shared_section, &pixels); |
52 if (!hbitmap) { | 53 if (!new_bitmap) { |
53 LOG(ERROR) << "CreateHBitmap failed"; | 54 LOG(ERROR) << "CreateHBitmap failed"; |
54 return false; | 55 return false; |
55 } | 56 } |
56 | 57 |
57 size_t row_bytes = skia::PlatformCanvasStrideForWidth(width); | 58 size_t row_bytes = skia::PlatformCanvasStrideForWidth(width); |
58 if (do_clear) | 59 if (do_clear) |
59 sk_bzero(pixels, row_bytes * height); | 60 sk_bzero(pixels, row_bytes * height); |
60 | 61 |
61 HDC hdc = CreateCompatibleDC(nullptr); | 62 HDC hdc = CreateCompatibleDC(nullptr); |
62 if (!hdc) { | 63 if (!hdc) { |
63 DeleteObject(hbitmap); | 64 DeleteObject(new_bitmap); |
64 return false; | 65 return false; |
65 } | 66 } |
66 SetGraphicsMode(hdc, GM_ADVANCED); | 67 SetGraphicsMode(hdc, GM_ADVANCED); |
67 | 68 |
68 int saveIndex = SaveDC(hdc); // so we can Restore in the delete callback | 69 HBITMAP prev_bitmap = static_cast<HBITMAP>(SelectObject(hdc, new_bitmap)); |
69 DCHECK_NE(saveIndex, 0); | 70 DCHECK(prev_bitmap); |
70 | |
71 // Be sure to select *after* we called SaveDC. | |
72 // Because we're using save/restore, we don't need to explicitly track the | |
73 // returned "previous" value. | |
74 SelectObject(hdc, hbitmap); | |
75 | 71 |
76 rec->fReleaseProc = DeleteHDCCallback; | 72 rec->fReleaseProc = DeleteHDCCallback; |
77 rec->fReleaseCtx = hdc; | 73 rec->fReleaseCtx = new HDCContextRec{hdc, prev_bitmap}; |
78 rec->fPixels = pixels; | 74 rec->fPixels = pixels; |
79 rec->fRowBytes = row_bytes; | 75 rec->fRowBytes = row_bytes; |
80 rec->fHandle = hdc; | 76 rec->fHandle = hdc; |
81 return true; | 77 return true; |
82 } | 78 } |
83 | 79 |
84 /** | 80 /** |
85 * Subclass of SkRasterHandleAllocator that returns an HDC as its "handle". | 81 * Subclass of SkRasterHandleAllocator that returns an HDC as its "handle". |
86 */ | 82 */ |
87 class GDIAllocator : public SkRasterHandleAllocator { | 83 class GDIAllocator : public SkRasterHandleAllocator { |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 if (failure_type == CRASH_ON_FAILURE) | 149 if (failure_type == CRASH_ON_FAILURE) |
154 SK_CRASH(); | 150 SK_CRASH(); |
155 return nullptr; | 151 return nullptr; |
156 } | 152 } |
157 | 153 |
158 HDC GetNativeDrawingContext(SkCanvas* canvas) { | 154 HDC GetNativeDrawingContext(SkCanvas* canvas) { |
159 return canvas ? static_cast<HDC>(canvas->accessTopRasterHandle()) : nullptr; | 155 return canvas ? static_cast<HDC>(canvas->accessTopRasterHandle()) : nullptr; |
160 } | 156 } |
161 | 157 |
162 } // namespace skia | 158 } // namespace skia |
OLD | NEW |