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

Side by Side Diff: skia/ext/bitmap_platform_device_win.cc

Issue 1321913002: Modified platform bitmap to support GDI being unavailable (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Minor stylistic changes for review. Created 5 years, 3 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 | « no previous file | 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 <windows.h> 5 #include <windows.h>
6 #include <psapi.h> 6 #include <psapi.h>
7 7
8 #include "base/debug/gdi_debug_util_win.h" 8 #include "base/debug/gdi_debug_util_win.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "skia/ext/bitmap_platform_device_win.h" 10 #include "skia/ext/bitmap_platform_device_win.h"
11 #include "skia/ext/platform_canvas.h" 11 #include "skia/ext/platform_canvas.h"
12 #include "third_party/skia/include/core/SkMatrix.h" 12 #include "third_party/skia/include/core/SkMatrix.h"
13 #include "third_party/skia/include/core/SkRefCnt.h" 13 #include "third_party/skia/include/core/SkRefCnt.h"
14 #include "third_party/skia/include/core/SkRegion.h" 14 #include "third_party/skia/include/core/SkRegion.h"
15 #include "third_party/skia/include/core/SkUtils.h" 15 #include "third_party/skia/include/core/SkUtils.h"
16 16
17 namespace { 17 namespace {
18 18
19 typedef decltype(GetProcessMitigationPolicy)* GetProcessMitigationPolicyType;
20
21 bool IsWin32kLockdownEnabled() {
22 static GetProcessMitigationPolicyType get_process_mitigation_policy_func =
23 reinterpret_cast<GetProcessMitigationPolicyType>(
24 GetProcAddress(
25 GetModuleHandle(L"kernel32.dll"),
26 "GetProcessMitigationPolicy"));
27
28 if (!get_process_mitigation_policy_func)
29 return false;
30
31 PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY policy = {0};
32 if (get_process_mitigation_policy_func(GetCurrentProcess(),
33 ProcessSystemCallDisablePolicy,
34 &policy,
35 sizeof(policy)))
36 return policy.DisallowWin32kSystemCalls != 0;
37
38 return false;
Will Harris 2015/09/04 16:26:33 I suppose I more meant make the return value of th
39 }
40
19 HBITMAP CreateHBitmap(int width, int height, bool is_opaque, 41 HBITMAP CreateHBitmap(int width, int height, bool is_opaque,
20 HANDLE shared_section, void** data) { 42 HANDLE shared_section, void** data) {
21 // CreateDIBSection appears to get unhappy if we create an empty bitmap, so 43 // CreateDIBSection appears to get unhappy if we create an empty bitmap, so
22 // just create a minimal bitmap 44 // just create a minimal bitmap
23 if ((width == 0) || (height == 0)) { 45 if ((width == 0) || (height == 0)) {
24 width = 1; 46 width = 1;
25 height = 1; 47 height = 1;
26 } 48 }
27 49
28 BITMAPINFOHEADER hdr = {0}; 50 BITMAPINFOHEADER hdr = {0};
(...skipping 21 matching lines...) Expand all
50 72
51 return hbitmap; 73 return hbitmap;
52 } 74 }
53 75
54 } // namespace 76 } // namespace
55 77
56 namespace skia { 78 namespace skia {
57 79
58 void DrawToNativeContext(SkCanvas* canvas, HDC hdc, int x, int y, 80 void DrawToNativeContext(SkCanvas* canvas, HDC hdc, int x, int y,
59 const RECT* src_rect) { 81 const RECT* src_rect) {
82 DCHECK(!IsWin32kLockdownEnabled());
60 PlatformDevice* platform_device = GetPlatformDevice(GetTopDevice(*canvas)); 83 PlatformDevice* platform_device = GetPlatformDevice(GetTopDevice(*canvas));
61 if (platform_device) 84 if (platform_device)
62 platform_device->DrawToHDC(hdc, x, y, src_rect); 85 platform_device->DrawToHDC(hdc, x, y, src_rect);
63 } 86 }
64 87
65 void PlatformDevice::DrawToHDC(HDC, int x, int y, const RECT* src_rect) {} 88 void PlatformDevice::DrawToHDC(HDC, int x, int y, const RECT* src_rect) {}
66 89
67 HDC BitmapPlatformDevice::GetBitmapDC() { 90 HDC BitmapPlatformDevice::GetBitmapDC() {
91 DCHECK(!IsWin32kLockdownEnabled());
68 if (!hdc_) { 92 if (!hdc_) {
69 hdc_ = CreateCompatibleDC(NULL); 93 hdc_ = CreateCompatibleDC(NULL);
70 InitializeDC(hdc_); 94 InitializeDC(hdc_);
71 old_hbitmap_ = static_cast<HBITMAP>(SelectObject(hdc_, hbitmap_)); 95 old_hbitmap_ = static_cast<HBITMAP>(SelectObject(hdc_, hbitmap_));
72 } 96 }
73 97
74 LoadConfig(); 98 LoadConfig();
75 return hdc_; 99 return hdc_;
76 } 100 }
77 101
78 void BitmapPlatformDevice::ReleaseBitmapDC() { 102 void BitmapPlatformDevice::ReleaseBitmapDC() {
79 SkASSERT(hdc_); 103 if (!IsWin32kLockdownEnabled()) {
80 SelectObject(hdc_, old_hbitmap_); 104 SkASSERT(hdc_);
81 DeleteDC(hdc_); 105 SelectObject(hdc_, old_hbitmap_);
82 hdc_ = NULL; 106 DeleteDC(hdc_);
83 old_hbitmap_ = NULL; 107 hdc_ = NULL;
108 old_hbitmap_ = NULL;
109 }
84 } 110 }
85 111
86 bool BitmapPlatformDevice::IsBitmapDCCreated() 112 bool BitmapPlatformDevice::IsBitmapDCCreated()
87 const { 113 const {
88 return hdc_ != NULL; 114 return hdc_ != NULL;
89 } 115 }
90 116
91 117
92 void BitmapPlatformDevice::SetMatrixClip( 118 void BitmapPlatformDevice::SetMatrixClip(
93 const SkMatrix& transform, 119 const SkMatrix& transform,
94 const SkRegion& region) { 120 const SkRegion& region) {
95 transform_ = transform; 121 transform_ = transform;
96 clip_region_ = region; 122 clip_region_ = region;
97 config_dirty_ = true; 123 config_dirty_ = true;
98 } 124 }
99 125
100 void BitmapPlatformDevice::LoadConfig() { 126 void BitmapPlatformDevice::LoadConfig() {
101 if (!config_dirty_ || !hdc_) 127 if (!config_dirty_ || !hdc_)
102 return; // Nothing to do. 128 return; // Nothing to do.
103 config_dirty_ = false; 129 config_dirty_ = false;
104 130
105 // Transform. 131 // Transform.
106 LoadTransformToDC(hdc_, transform_); 132 LoadTransformToDC(hdc_, transform_);
107 LoadClippingRegionToDC(hdc_, clip_region_, transform_); 133 LoadClippingRegionToDC(hdc_, clip_region_, transform_);
108 } 134 }
109 135
110 static void DeleteHBitmapCallback(void* addr, void* context) { 136 static void DeleteHBitmapCallback(void* addr, void* context) {
111 DeleteObject(static_cast<HBITMAP>(context)); 137 // If context is not NULL then it's a valid HBITMAP to delete.
138 // Otherwise we just unmap the pixel memory.
139 if (context)
140 DeleteObject(static_cast<HBITMAP>(context));
141 else
142 UnmapViewOfFile(addr);
112 } 143 }
113 144
114 static bool InstallHBitmapPixels(SkBitmap* bitmap, int width, int height, 145 static bool InstallHBitmapPixels(SkBitmap* bitmap, int width, int height,
115 bool is_opaque, void* data, HBITMAP hbitmap) { 146 bool is_opaque, void* data, HBITMAP hbitmap) {
116 const SkAlphaType at = is_opaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType; 147 const SkAlphaType at = is_opaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType;
117 const SkImageInfo info = SkImageInfo::MakeN32(width, height, at); 148 const SkImageInfo info = SkImageInfo::MakeN32(width, height, at);
118 const size_t rowBytes = info.minRowBytes(); 149 const size_t rowBytes = info.minRowBytes();
119 SkColorTable* color_table = NULL; 150 SkColorTable* color_table = NULL;
120 return bitmap->installPixels(info, data, rowBytes, color_table, 151 return bitmap->installPixels(info, data, rowBytes, color_table,
121 DeleteHBitmapCallback, hbitmap); 152 DeleteHBitmapCallback, hbitmap);
122 } 153 }
123 154
124 // We use this static factory function instead of the regular constructor so 155 // We use this static factory function instead of the regular constructor so
125 // that we can create the pixel data before calling the constructor. This is 156 // that we can create the pixel data before calling the constructor. This is
126 // required so that we can call the base class' constructor with the pixel 157 // required so that we can call the base class' constructor with the pixel
127 // data. 158 // data.
128 BitmapPlatformDevice* BitmapPlatformDevice::Create( 159 BitmapPlatformDevice* BitmapPlatformDevice::Create(
129 int width, 160 int width,
130 int height, 161 int height,
131 bool is_opaque, 162 bool is_opaque,
132 HANDLE shared_section, 163 HANDLE shared_section,
133 bool do_clear) { 164 bool do_clear) {
134 165
135 void* data; 166 void* data;
136 HBITMAP hbitmap = CreateHBitmap(width, height, is_opaque, shared_section, 167
168 HBITMAP hbitmap = NULL;
169
170 if (IsWin32kLockdownEnabled()) {
171 CHECK(shared_section != NULL);
172 data = MapViewOfFile(shared_section, FILE_MAP_WRITE,
173 0, 0, width * height * 4);
174 DCHECK(data != NULL);
175 if (!data)
176 return NULL;
177 } else {
178 hbitmap = CreateHBitmap(width, height, is_opaque, shared_section,
137 &data); 179 &data);
138 if (!hbitmap) 180 if (!hbitmap)
139 return NULL; 181 return NULL;
182 }
140 183
141 SkBitmap bitmap; 184 SkBitmap bitmap;
142 if (!InstallHBitmapPixels(&bitmap, width, height, is_opaque, data, hbitmap)) 185 if (!InstallHBitmapPixels(&bitmap, width, height, is_opaque, data, hbitmap))
143 return NULL; 186 return NULL;
144 187
145 if (do_clear) 188 if (do_clear)
146 bitmap.eraseColor(0); 189 bitmap.eraseColor(0);
147 190
148 #ifndef NDEBUG 191 #ifndef NDEBUG
149 // If we were given data, then don't clobber it! 192 // If we were given data, then don't clobber it!
(...skipping 23 matching lines...) Expand all
173 const SkBitmap& bitmap) 216 const SkBitmap& bitmap)
174 : SkBitmapDevice(bitmap), 217 : SkBitmapDevice(bitmap),
175 hbitmap_(hbitmap), 218 hbitmap_(hbitmap),
176 old_hbitmap_(NULL), 219 old_hbitmap_(NULL),
177 hdc_(NULL), 220 hdc_(NULL),
178 config_dirty_(true), // Want to load the config next time. 221 config_dirty_(true), // Want to load the config next time.
179 transform_(SkMatrix::I()) { 222 transform_(SkMatrix::I()) {
180 // The data object is already ref'ed for us by create(). 223 // The data object is already ref'ed for us by create().
181 SkDEBUGCODE(begin_paint_count_ = 0); 224 SkDEBUGCODE(begin_paint_count_ = 0);
182 SetPlatformDevice(this, this); 225 SetPlatformDevice(this, this);
183 // Initialize the clip region to the entire bitmap. 226 if (hbitmap) {
184 BITMAP bitmap_data; 227 // Initialize the clip region to the entire bitmap.
185 if (GetObject(hbitmap_, sizeof(BITMAP), &bitmap_data)) { 228 BITMAP bitmap_data;
186 SkIRect rect; 229 if (GetObject(hbitmap_, sizeof(BITMAP), &bitmap_data)) {
187 rect.set(0, 0, bitmap_data.bmWidth, bitmap_data.bmHeight); 230 SkIRect rect;
188 clip_region_ = SkRegion(rect); 231 rect.set(0, 0, bitmap_data.bmWidth, bitmap_data.bmHeight);
232 clip_region_ = SkRegion(rect);
233 }
189 } 234 }
190 } 235 }
191 236
192 BitmapPlatformDevice::~BitmapPlatformDevice() { 237 BitmapPlatformDevice::~BitmapPlatformDevice() {
193 SkASSERT(begin_paint_count_ == 0); 238 SkASSERT(begin_paint_count_ == 0);
194 if (hdc_) 239 if (hdc_)
195 ReleaseBitmapDC(); 240 ReleaseBitmapDC();
196 } 241 }
197 242
198 HDC BitmapPlatformDevice::BeginPlatformPaint() { 243 HDC BitmapPlatformDevice::BeginPlatformPaint() {
199 SkDEBUGCODE(begin_paint_count_++); 244 SkDEBUGCODE(begin_paint_count_++);
200 return GetBitmapDC(); 245 return GetBitmapDC();
201 } 246 }
202 247
203 void BitmapPlatformDevice::EndPlatformPaint() { 248 void BitmapPlatformDevice::EndPlatformPaint() {
204 SkASSERT(begin_paint_count_--); 249 SkASSERT(begin_paint_count_--);
205 PlatformDevice::EndPlatformPaint(); 250 PlatformDevice::EndPlatformPaint();
206 } 251 }
207 252
208 void BitmapPlatformDevice::setMatrixClip(const SkMatrix& transform, 253 void BitmapPlatformDevice::setMatrixClip(const SkMatrix& transform,
209 const SkRegion& region, 254 const SkRegion& region,
210 const SkClipStack&) { 255 const SkClipStack&) {
211 SetMatrixClip(transform, region); 256 SetMatrixClip(transform, region);
212 } 257 }
213 258
214 void BitmapPlatformDevice::DrawToHDC(HDC dc, int x, int y, 259 void BitmapPlatformDevice::DrawToHDC(HDC dc, int x, int y,
215 const RECT* src_rect) { 260 const RECT* src_rect) {
261 DCHECK(!IsWin32kLockdownEnabled());
262
216 bool created_dc = !IsBitmapDCCreated(); 263 bool created_dc = !IsBitmapDCCreated();
217 HDC source_dc = BeginPlatformPaint(); 264 HDC source_dc = BeginPlatformPaint();
218 265
219 RECT temp_rect; 266 RECT temp_rect;
220 if (!src_rect) { 267 if (!src_rect) {
221 temp_rect.left = 0; 268 temp_rect.left = 0;
222 temp_rect.right = width(); 269 temp_rect.right = width();
223 temp_rect.top = 0; 270 temp_rect.top = 0;
224 temp_rect.bottom = height(); 271 temp_rect.bottom = height();
225 src_rect = &temp_rect; 272 src_rect = &temp_rect;
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 345
299 PlatformBitmap::~PlatformBitmap() { 346 PlatformBitmap::~PlatformBitmap() {
300 if (surface_) { 347 if (surface_) {
301 if (platform_extra_) 348 if (platform_extra_)
302 SelectObject(surface_, reinterpret_cast<HGDIOBJ>(platform_extra_)); 349 SelectObject(surface_, reinterpret_cast<HGDIOBJ>(platform_extra_));
303 DeleteDC(surface_); 350 DeleteDC(surface_);
304 } 351 }
305 } 352 }
306 353
307 bool PlatformBitmap::Allocate(int width, int height, bool is_opaque) { 354 bool PlatformBitmap::Allocate(int width, int height, bool is_opaque) {
355 DCHECK(!IsWin32kLockdownEnabled());
308 void* data; 356 void* data;
309 HBITMAP hbitmap = CreateHBitmap(width, height, is_opaque, 0, &data); 357 HBITMAP hbitmap = CreateHBitmap(width, height, is_opaque, 0, &data);
310 if (!hbitmap) 358 if (!hbitmap)
311 return false; 359 return false;
312 360
313 surface_ = CreateCompatibleDC(NULL); 361 surface_ = CreateCompatibleDC(NULL);
314 InitializeDC(surface_); 362 InitializeDC(surface_);
315 // When the memory DC is created, its display surface is exactly one 363 // When the memory DC is created, its display surface is exactly one
316 // monochrome pixel wide and one monochrome pixel high. Save this object 364 // monochrome pixel wide and one monochrome pixel high. Save this object
317 // off, we'll restore it just before deleting the memory DC. 365 // off, we'll restore it just before deleting the memory DC.
318 HGDIOBJ stock_bitmap = SelectObject(surface_, hbitmap); 366 HGDIOBJ stock_bitmap = SelectObject(surface_, hbitmap);
319 platform_extra_ = reinterpret_cast<intptr_t>(stock_bitmap); 367 platform_extra_ = reinterpret_cast<intptr_t>(stock_bitmap);
320 368
321 if (!InstallHBitmapPixels(&bitmap_, width, height, is_opaque, data, hbitmap)) 369 if (!InstallHBitmapPixels(&bitmap_, width, height, is_opaque, data, hbitmap))
322 return false; 370 return false;
323 bitmap_.lockPixels(); 371 bitmap_.lockPixels();
324 372
325 return true; 373 return true;
326 } 374 }
327 375
328 } // namespace skia 376 } // namespace skia
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698