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

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

Issue 1963713002: Replace setMatrixClip() with BeginPlatformPaint() logic (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: compensate for any outstanding saveLayer() calls Created 4 years, 7 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/bitmap_platform_device_win.h ('k') | skia/ext/platform_canvas.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) 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 #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/logging.h" 10 #include "base/logging.h"
11 #include "base/win/win_util.h" 11 #include "base/win/win_util.h"
12 #include "skia/ext/bitmap_platform_device_win.h" 12 #include "skia/ext/bitmap_platform_device_win.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/SkRegion.h" 18 #include "third_party/skia/include/core/SkRect.h"
19 19
20 namespace { 20 namespace {
21 21
22 HBITMAP CreateHBitmap(int width, int height, bool is_opaque, 22 HBITMAP CreateHBitmap(int width, int height, bool is_opaque,
23 HANDLE shared_section, void** data) { 23 HANDLE shared_section, void** data) {
24 // CreateDIBSection appears to get unhappy if we create an empty bitmap, so 24 // CreateDIBSection appears to get unhappy if we create an empty bitmap, so
25 // just create a minimal bitmap 25 // just create a minimal bitmap
26 if ((width == 0) || (height == 0)) { 26 if ((width == 0) || (height == 0)) {
27 width = 1; 27 width = 1;
28 height = 1; 28 height = 1;
(...skipping 30 matching lines...) Expand all
59 xf.eM11 = matrix[SkMatrix::kMScaleX]; 59 xf.eM11 = matrix[SkMatrix::kMScaleX];
60 xf.eM21 = matrix[SkMatrix::kMSkewX]; 60 xf.eM21 = matrix[SkMatrix::kMSkewX];
61 xf.eDx = matrix[SkMatrix::kMTransX]; 61 xf.eDx = matrix[SkMatrix::kMTransX];
62 xf.eM12 = matrix[SkMatrix::kMSkewY]; 62 xf.eM12 = matrix[SkMatrix::kMSkewY];
63 xf.eM22 = matrix[SkMatrix::kMScaleY]; 63 xf.eM22 = matrix[SkMatrix::kMScaleY];
64 xf.eDy = matrix[SkMatrix::kMTransY]; 64 xf.eDy = matrix[SkMatrix::kMTransY];
65 SetWorldTransform(dc, &xf); 65 SetWorldTransform(dc, &xf);
66 } 66 }
67 67
68 void LoadClippingRegionToDC(HDC context, 68 void LoadClippingRegionToDC(HDC context,
69 const SkRegion& region, 69 const SkIRect& clip_bounds,
70 const SkMatrix& transformation) { 70 const SkMatrix& transformation) {
71 HRGN hrgn; 71 HRGN hrgn = CreateRectRgnIndirect(&skia::SkIRectToRECT(clip_bounds));
72 if (region.isEmpty()) {
73 // region can be empty, in which case everything will be clipped.
74 hrgn = CreateRectRgn(0, 0, 0, 0);
75 } else if (region.isRect()) {
76 // We don't apply transformation, because the translation is already applied
77 // to the region.
78 hrgn = CreateRectRgnIndirect(&skia::SkIRectToRECT(region.getBounds()));
79 } else {
80 hrgn = CreateRectRgnIndirect(&skia::SkIRectToRECT(region.getBounds()));
81 SkASSERT(!"Region clipping is being deprecated; this shouldn't fire.");
82 }
83 int result = SelectClipRgn(context, hrgn); 72 int result = SelectClipRgn(context, hrgn);
84 SkASSERT(result != ERROR); 73 SkASSERT(result != ERROR);
85 result = DeleteObject(hrgn); 74 result = DeleteObject(hrgn);
86 SkASSERT(result != 0); 75 SkASSERT(result != 0);
87 } 76 }
88 77
89 } // namespace 78 } // namespace
90 79
91 namespace skia { 80 namespace skia {
92 81
93 void DrawToNativeContext(SkCanvas* canvas, HDC hdc, int x, int y, 82 void DrawToNativeContext(SkCanvas* canvas, HDC destination_hdc, int x, int y,
94 const RECT* src_rect) { 83 const RECT* src_rect) {
84 ScopedPlatformPaint p(canvas);
95 PlatformDevice* platform_device = GetPlatformDevice(GetTopDevice(*canvas)); 85 PlatformDevice* platform_device = GetPlatformDevice(GetTopDevice(*canvas));
96 if (platform_device) 86 if (platform_device)
97 platform_device->DrawToHDC(hdc, x, y, src_rect); 87 platform_device->DrawToHDC(p.GetPlatformSurface(), destination_hdc, x, y,
88 src_rect, canvas->getTotalMatrix());
89
98 } 90 }
99 91
100 void PlatformDevice::DrawToHDC(HDC, int x, int y, const RECT* src_rect) {} 92 void PlatformDevice::DrawToHDC(HDC, HDC, int x, int y, const RECT* src_rect,
93 const SkMatrix& transform) {}
101 94
102 HDC BitmapPlatformDevice::GetBitmapDC() { 95 HDC BitmapPlatformDevice::GetBitmapDC(const SkMatrix& transform,
96 const SkIRect& clip_bounds) {
103 if (!hdc_) { 97 if (!hdc_) {
104 hdc_ = CreateCompatibleDC(NULL); 98 hdc_ = CreateCompatibleDC(NULL);
105 InitializeDC(hdc_); 99 InitializeDC(hdc_);
106 old_hbitmap_ = static_cast<HBITMAP>(SelectObject(hdc_, hbitmap_)); 100 old_hbitmap_ = static_cast<HBITMAP>(SelectObject(hdc_, hbitmap_));
107 } 101 }
108 102
109 LoadConfig(); 103 LoadConfig(transform, clip_bounds);
110 return hdc_; 104 return hdc_;
111 } 105 }
112 106
113 void BitmapPlatformDevice::ReleaseBitmapDC() { 107 void BitmapPlatformDevice::ReleaseBitmapDC() {
114 SkASSERT(hdc_); 108 SkASSERT(hdc_);
115 SelectObject(hdc_, old_hbitmap_); 109 SelectObject(hdc_, old_hbitmap_);
116 DeleteDC(hdc_); 110 DeleteDC(hdc_);
117 hdc_ = NULL; 111 hdc_ = NULL;
118 old_hbitmap_ = NULL; 112 old_hbitmap_ = NULL;
119 } 113 }
120 114
121 bool BitmapPlatformDevice::IsBitmapDCCreated() 115 bool BitmapPlatformDevice::IsBitmapDCCreated()
122 const { 116 const {
123 return hdc_ != NULL; 117 return hdc_ != NULL;
124 } 118 }
125 119
126 120 void BitmapPlatformDevice::LoadConfig(const SkMatrix& transform,
127 void BitmapPlatformDevice::SetMatrixClip( 121 const SkIRect& clip_bounds) {
128 const SkMatrix& transform, 122 if (!hdc_)
129 const SkRegion& region) {
130 transform_ = transform;
131 clip_region_ = region;
132 config_dirty_ = true;
133 }
134
135 void BitmapPlatformDevice::LoadConfig() {
136 if (!config_dirty_ || !hdc_)
137 return; // Nothing to do. 123 return; // Nothing to do.
138 config_dirty_ = false;
139 124
140 // Transform. 125 // Transform.
141 LoadTransformToDC(hdc_, transform_); 126 LoadTransformToDC(hdc_, transform);
142 LoadClippingRegionToDC(hdc_, clip_region_, transform_); 127 LoadClippingRegionToDC(hdc_, clip_bounds, transform);
143 } 128 }
144 129
145 static void DeleteHBitmapCallback(void* addr, void* context) { 130 static void DeleteHBitmapCallback(void* addr, void* context) {
146 // If context is not NULL then it's a valid HBITMAP to delete. 131 // If context is not NULL then it's a valid HBITMAP to delete.
147 // Otherwise we just unmap the pixel memory. 132 // Otherwise we just unmap the pixel memory.
148 if (context) 133 if (context)
149 DeleteObject(static_cast<HBITMAP>(context)); 134 DeleteObject(static_cast<HBITMAP>(context));
150 else 135 else
151 UnmapViewOfFile(addr); 136 UnmapViewOfFile(addr);
152 } 137 }
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 } 207 }
223 208
224 // The device will own the HBITMAP, which corresponds to also owning the pixel 209 // The device will own the HBITMAP, which corresponds to also owning the pixel
225 // data. Therefore, we do not transfer ownership to the SkBitmapDevice's bitmap. 210 // data. Therefore, we do not transfer ownership to the SkBitmapDevice's bitmap.
226 BitmapPlatformDevice::BitmapPlatformDevice( 211 BitmapPlatformDevice::BitmapPlatformDevice(
227 HBITMAP hbitmap, 212 HBITMAP hbitmap,
228 const SkBitmap& bitmap) 213 const SkBitmap& bitmap)
229 : SkBitmapDevice(bitmap), 214 : SkBitmapDevice(bitmap),
230 hbitmap_(hbitmap), 215 hbitmap_(hbitmap),
231 old_hbitmap_(NULL), 216 old_hbitmap_(NULL),
232 hdc_(NULL), 217 hdc_(NULL) {
233 config_dirty_(true), // Want to load the config next time.
234 transform_(SkMatrix::I()) {
235 // The data object is already ref'ed for us by create(). 218 // The data object is already ref'ed for us by create().
236 if (hbitmap) { 219 if (hbitmap) {
237 SetPlatformDevice(this, this); 220 SetPlatformDevice(this, this);
238 // Initialize the clip region to the entire bitmap.
239 BITMAP bitmap_data; 221 BITMAP bitmap_data;
240 if (GetObject(hbitmap_, sizeof(BITMAP), &bitmap_data)) { 222 GetObject(hbitmap_, sizeof(BITMAP), &bitmap_data);
241 SkIRect rect;
242 rect.set(0, 0, bitmap_data.bmWidth, bitmap_data.bmHeight);
243 clip_region_ = SkRegion(rect);
244 }
245 } 223 }
246 } 224 }
247 225
248 BitmapPlatformDevice::~BitmapPlatformDevice() { 226 BitmapPlatformDevice::~BitmapPlatformDevice() {
249 if (hdc_) 227 if (hdc_)
250 ReleaseBitmapDC(); 228 ReleaseBitmapDC();
251 } 229 }
252 230
253 HDC BitmapPlatformDevice::BeginPlatformPaint() { 231 HDC BitmapPlatformDevice::BeginPlatformPaint(const SkMatrix& transform,
254 return GetBitmapDC(); 232 const SkIRect& clip_bounds) {
233 return GetBitmapDC(transform, clip_bounds);
255 } 234 }
256 235
257 void BitmapPlatformDevice::setMatrixClip(const SkMatrix& transform, 236 void BitmapPlatformDevice::DrawToHDC(HDC source_dc, HDC destination_dc,
258 const SkRegion& region, 237 int x, int y,
259 const SkClipStack&) { 238 const RECT* src_rect,
260 SetMatrixClip(transform, region); 239 const SkMatrix& transform) {
261 }
262
263 void BitmapPlatformDevice::DrawToHDC(HDC dc, int x, int y,
264 const RECT* src_rect) {
265 bool created_dc = !IsBitmapDCCreated(); 240 bool created_dc = !IsBitmapDCCreated();
266 HDC source_dc = BeginPlatformPaint();
267 241
268 RECT temp_rect; 242 RECT temp_rect;
269 if (!src_rect) { 243 if (!src_rect) {
270 temp_rect.left = 0; 244 temp_rect.left = 0;
271 temp_rect.right = width(); 245 temp_rect.right = width();
272 temp_rect.top = 0; 246 temp_rect.top = 0;
273 temp_rect.bottom = height(); 247 temp_rect.bottom = height();
274 src_rect = &temp_rect; 248 src_rect = &temp_rect;
275 } 249 }
276 250
277 int copy_width = src_rect->right - src_rect->left; 251 int copy_width = src_rect->right - src_rect->left;
278 int copy_height = src_rect->bottom - src_rect->top; 252 int copy_height = src_rect->bottom - src_rect->top;
279 253
280 // We need to reset the translation for our bitmap or (0,0) won't be in the 254 // We need to reset the translation for our bitmap or (0,0) won't be in the
281 // upper left anymore 255 // upper left anymore
282 SkMatrix identity; 256 SkMatrix identity;
283 identity.reset(); 257 identity.reset();
284 258
285 LoadTransformToDC(source_dc, identity); 259 LoadTransformToDC(source_dc, identity);
286 if (isOpaque()) { 260 if (isOpaque()) {
287 BitBlt(dc, 261 BitBlt(destination_dc,
288 x, 262 x,
289 y, 263 y,
290 copy_width, 264 copy_width,
291 copy_height, 265 copy_height,
292 source_dc, 266 source_dc,
293 src_rect->left, 267 src_rect->left,
294 src_rect->top, 268 src_rect->top,
295 SRCCOPY); 269 SRCCOPY);
296 } else { 270 } else {
297 SkASSERT(copy_width != 0 && copy_height != 0); 271 SkASSERT(copy_width != 0 && copy_height != 0);
298 BLENDFUNCTION blend_function = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA}; 272 BLENDFUNCTION blend_function = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
299 GdiAlphaBlend(dc, 273 GdiAlphaBlend(destination_dc,
300 x, 274 x,
301 y, 275 y,
302 copy_width, 276 copy_width,
303 copy_height, 277 copy_height,
304 source_dc, 278 source_dc,
305 src_rect->left, 279 src_rect->left,
306 src_rect->top, 280 src_rect->top,
307 copy_width, 281 copy_width,
308 copy_height, 282 copy_height,
309 blend_function); 283 blend_function);
310 } 284 }
311 LoadTransformToDC(source_dc, transform_); 285 LoadTransformToDC(source_dc, transform);
312 286
313 if (created_dc) 287 if (created_dc)
314 ReleaseBitmapDC(); 288 ReleaseBitmapDC();
315 } 289 }
316 290
317 const SkBitmap& BitmapPlatformDevice::onAccessBitmap() { 291 const SkBitmap& BitmapPlatformDevice::onAccessBitmap() {
318 // FIXME(brettw) OPTIMIZATION: We should only flush if we know a GDI 292 // FIXME(brettw) OPTIMIZATION: We should only flush if we know a GDI
319 // operation has occurred on our DC. 293 // operation has occurred on our DC.
320 if (IsBitmapDCCreated()) 294 if (IsBitmapDCCreated())
321 GdiFlush(); 295 GdiFlush();
(...skipping 14 matching lines...) Expand all
336 int height, 310 int height,
337 bool is_opaque, 311 bool is_opaque,
338 HANDLE shared_section, 312 HANDLE shared_section,
339 OnFailureType failureType) { 313 OnFailureType failureType) {
340 sk_sp<SkBaseDevice> dev( 314 sk_sp<SkBaseDevice> dev(
341 BitmapPlatformDevice::Create(width, height, is_opaque, shared_section)); 315 BitmapPlatformDevice::Create(width, height, is_opaque, shared_section));
342 return CreateCanvas(dev, failureType); 316 return CreateCanvas(dev, failureType);
343 } 317 }
344 318
345 } // namespace skia 319 } // namespace skia
OLDNEW
« no previous file with comments | « skia/ext/bitmap_platform_device_win.h ('k') | skia/ext/platform_canvas.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698