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

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

Issue 14903: Reverting 7318. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 12 years 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 | Annotate | Revision Log
« no previous file with comments | « skia/ext/bitmap_platform_device_win.h ('k') | skia/ext/platform_canvas_win.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) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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 "skia/ext/bitmap_platform_device_win.h" 5 #include "skia/ext/bitmap_platform_device_win.h"
6 6
7 #include "base/gfx/gdi_util.h"
8 #include "base/logging.h"
9 #include "SkMatrix.h" 7 #include "SkMatrix.h"
8 #include "SkRefCnt.h"
10 #include "SkRegion.h" 9 #include "SkRegion.h"
11 #include "SkUtils.h" 10 #include "SkUtils.h"
12 11
13 namespace skia { 12 namespace skia {
14 13
15 // When Windows draws text, is sets the fourth byte (which Skia uses for alpha) 14 // When Windows draws text, is sets the fourth byte (which Skia uses for alpha)
16 // to zero. This means that if we try compositing with text that Windows has 15 // to zero. This means that if we try compositing with text that Windows has
17 // drawn, we get invalid color values (if the alpha is 0, the other channels 16 // drawn, we get invalid color values (if the alpha is 0, the other channels
18 // should be 0 since Skia uses premultiplied colors) and strange results. 17 // should be 0 since Skia uses premultiplied colors) and strange results.
19 // 18 //
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 // See the declaration of kMagicTransparencyColor at the top of the file. 92 // See the declaration of kMagicTransparencyColor at the top of the file.
94 void FixupAlphaBeforeCompositing(uint32_t* pixel) { 93 void FixupAlphaBeforeCompositing(uint32_t* pixel) {
95 if (*pixel == kMagicTransparencyColor) 94 if (*pixel == kMagicTransparencyColor)
96 *pixel = 0; 95 *pixel = 0;
97 else 96 else
98 *pixel |= 0xFF000000; 97 *pixel |= 0xFF000000;
99 } 98 }
100 99
101 } // namespace 100 } // namespace
102 101
103 class BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData 102 class BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData : public SkRefCnt {
104 : public base::RefCounted<BitmapPlatformDeviceWinData> {
105 public: 103 public:
106 explicit BitmapPlatformDeviceWinData(HBITMAP hbitmap); 104 explicit BitmapPlatformDeviceWinData(HBITMAP hbitmap);
107 105
108 // Create/destroy hdc_, which is the memory DC for our bitmap data. 106 // Create/destroy hdc_, which is the memory DC for our bitmap data.
109 HDC GetBitmapDC(); 107 HDC GetBitmapDC();
110 void ReleaseBitmapDC(); 108 void ReleaseBitmapDC();
111 bool IsBitmapDCCreated() const; 109 bool IsBitmapDCCreated() const;
112 110
113 // Sets the transform and clip operations. This will not update the DC, 111 // Sets the transform and clip operations. This will not update the DC,
114 // but will mark the config as dirty. The next call of LoadConfig will 112 // but will mark the config as dirty. The next call of LoadConfig will
(...skipping 22 matching lines...) Expand all
137 bool config_dirty_; 135 bool config_dirty_;
138 136
139 // Translation assigned to the DC: we need to keep track of this separately 137 // Translation assigned to the DC: we need to keep track of this separately
140 // so it can be updated even if the DC isn't created yet. 138 // so it can be updated even if the DC isn't created yet.
141 SkMatrix transform_; 139 SkMatrix transform_;
142 140
143 // The current clipping 141 // The current clipping
144 SkRegion clip_region_; 142 SkRegion clip_region_;
145 143
146 private: 144 private:
147 friend class base::RefCounted<BitmapPlatformDeviceWinData>; 145 virtual ~BitmapPlatformDeviceWinData();
148 ~BitmapPlatformDeviceWinData();
149 146
150 DISALLOW_EVIL_CONSTRUCTORS(BitmapPlatformDeviceWinData); 147 // Copy & assign are not supported.
148 BitmapPlatformDeviceWinData(const BitmapPlatformDeviceWinData&);
149 BitmapPlatformDeviceWinData& operator=(const BitmapPlatformDeviceWinData&);
151 }; 150 };
152 151
153 BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData::BitmapPlatformDeviceWinDat a( 152 BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData::BitmapPlatformDeviceWinDat a(
154 HBITMAP hbitmap) 153 HBITMAP hbitmap)
155 : hbitmap_(hbitmap), 154 : hbitmap_(hbitmap),
156 hdc_(NULL), 155 hdc_(NULL),
157 config_dirty_(true) { // Want to load the config next time. 156 config_dirty_(true) { // Want to load the config next time.
158 // Initialize the clip region to the entire bitmap. 157 // Initialize the clip region to the entire bitmap.
159 BITMAP bitmap_data; 158 BITMAP bitmap_data;
160 if (GetObject(hbitmap_, sizeof(BITMAP), &bitmap_data)) { 159 if (GetObject(hbitmap_, sizeof(BITMAP), &bitmap_data)) {
(...skipping 22 matching lines...) Expand all
183 // monochrome pixel wide and one monochrome pixel high. Since we select our 182 // monochrome pixel wide and one monochrome pixel high. Since we select our
184 // own bitmap, we must delete the previous one. 183 // own bitmap, we must delete the previous one.
185 DeleteObject(old_bitmap); 184 DeleteObject(old_bitmap);
186 } 185 }
187 186
188 LoadConfig(); 187 LoadConfig();
189 return hdc_; 188 return hdc_;
190 } 189 }
191 190
192 void BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData::ReleaseBitmapDC() { 191 void BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData::ReleaseBitmapDC() {
193 DCHECK(hdc_); 192 SkASSERT(hdc_);
194 DeleteDC(hdc_); 193 DeleteDC(hdc_);
195 hdc_ = NULL; 194 hdc_ = NULL;
196 } 195 }
197 196
198 bool BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData::IsBitmapDCCreated() 197 bool BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData::IsBitmapDCCreated()
199 const { 198 const {
200 return hdc_ != NULL; 199 return hdc_ != NULL;
201 } 200 }
202 201
203 202
(...skipping 16 matching lines...) Expand all
220 // We don't use transform_ for the clipping region since the translation is 219 // We don't use transform_ for the clipping region since the translation is
221 // already applied to offset_x_ and offset_y_. 220 // already applied to offset_x_ and offset_y_.
222 t.reset(); 221 t.reset();
223 LoadClippingRegionToDC(hdc_, clip_region_, t); 222 LoadClippingRegionToDC(hdc_, clip_region_, t);
224 } 223 }
225 224
226 // We use this static factory function instead of the regular constructor so 225 // We use this static factory function instead of the regular constructor so
227 // that we can create the pixel data before calling the constructor. This is 226 // that we can create the pixel data before calling the constructor. This is
228 // required so that we can call the base class' constructor with the pixel 227 // required so that we can call the base class' constructor with the pixel
229 // data. 228 // data.
230 BitmapPlatformDeviceWin* BitmapPlatformDeviceWin::create(HDC screen_dc, 229 BitmapPlatformDeviceWin* BitmapPlatformDeviceWin::create(
231 int width, 230 HDC screen_dc,
232 int height, 231 int width,
233 bool is_opaque, 232 int height,
234 HANDLE shared_section) { 233 bool is_opaque,
234 HANDLE shared_section) {
235 SkBitmap bitmap; 235 SkBitmap bitmap;
236 236
237 // CreateDIBSection appears to get unhappy if we create an empty bitmap, so 237 // CreateDIBSection appears to get unhappy if we create an empty bitmap, so
238 // just create a minimal bitmap 238 // just create a minimal bitmap
239 if ((width == 0) || (height == 0)) { 239 if ((width == 0) || (height == 0)) {
240 width = 1; 240 width = 1;
241 height = 1; 241 height = 1;
242 } 242 }
243 243
244 BITMAPINFOHEADER hdr = {0}; 244 BITMAPINFOHEADER hdr = {0};
245 gfx::CreateBitmapHeader(width, height, &hdr); 245 hdr.biSize = sizeof(BITMAPINFOHEADER);
246 hdr.biWidth = width;
247 hdr.biHeight = -height; // minus means top-down bitmap
248 hdr.biPlanes = 1;
249 hdr.biBitCount = 32;
250 hdr.biCompression = BI_RGB; // no compression
251 hdr.biSizeImage = 0;
252 hdr.biXPelsPerMeter = 1;
253 hdr.biYPelsPerMeter = 1;
254 hdr.biClrUsed = 0;
255 hdr.biClrImportant = 0;
246 256
247 void* data = NULL; 257 void* data = NULL;
248 HBITMAP hbitmap = CreateDIBSection(screen_dc, 258 HBITMAP hbitmap = CreateDIBSection(screen_dc,
249 reinterpret_cast<BITMAPINFO*>(&hdr), 0, 259 reinterpret_cast<BITMAPINFO*>(&hdr), 0,
250 &data, 260 &data,
251 shared_section, 0); 261 shared_section, 0);
252 262
253 // If we run out of GDI objects or some other error occurs, we won't get a 263 // If we run out of GDI objects or some other error occurs, we won't get a
254 // bitmap here. This will cause us to crash later because the data pointer is 264 // bitmap here. This will cause us to crash later because the data pointer is
255 // NULL. To make sure that we can assign blame for those crashes to this code, 265 // NULL. To make sure that we can assign blame for those crashes to this code,
256 // we deliberately crash here, even in release mode. 266 // we deliberately crash here, even in release mode.
257 if (!hbitmap) { 267 if (!hbitmap) {
258 DWORD error = GetLastError(); 268 DWORD error = GetLastError();
259 LOG(ERROR) << "CreateDIBSection Failed. Error: " << error << "\n";
260 return NULL; 269 return NULL;
261 } 270 }
262 271
263 bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height); 272 bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
264 bitmap.setPixels(data); 273 bitmap.setPixels(data);
265 bitmap.setIsOpaque(is_opaque); 274 bitmap.setIsOpaque(is_opaque);
266 275
267 if (is_opaque) { 276 if (is_opaque) {
268 #ifndef NDEBUG 277 #ifndef NDEBUG
269 // To aid in finding bugs, we set the background color to something 278 // To aid in finding bugs, we set the background color to something
270 // obviously wrong so it will be noticable when it is not cleared 279 // obviously wrong so it will be noticable when it is not cleared
271 bitmap.eraseARGB(255, 0, 255, 128); // bright bluish green 280 bitmap.eraseARGB(255, 0, 255, 128); // bright bluish green
272 #endif 281 #endif
273 } else { 282 } else {
274 // A transparent layer is requested: fill with our magic "transparent" 283 // A transparent layer is requested: fill with our magic "transparent"
275 // color, see the declaration of kMagicTransparencyColor above 284 // color, see the declaration of kMagicTransparencyColor above
276 sk_memset32(static_cast<uint32_t*>(data), kMagicTransparencyColor, 285 sk_memset32(static_cast<uint32_t*>(data), kMagicTransparencyColor,
277 width * height); 286 width * height);
278 } 287 }
279 288
280 // The device object will take ownership of the HBITMAP. 289 // The device object will take ownership of the HBITMAP. The initial refcount
290 // of the data object will be 1, which is what the constructor expects.
281 return new BitmapPlatformDeviceWin(new BitmapPlatformDeviceWinData(hbitmap), 291 return new BitmapPlatformDeviceWin(new BitmapPlatformDeviceWinData(hbitmap),
282 bitmap); 292 bitmap);
283 } 293 }
284 294
285 // The device will own the HBITMAP, which corresponds to also owning the pixel 295 // The device will own the HBITMAP, which corresponds to also owning the pixel
286 // data. Therefore, we do not transfer ownership to the SkDevice's bitmap. 296 // data. Therefore, we do not transfer ownership to the SkDevice's bitmap.
287 BitmapPlatformDeviceWin::BitmapPlatformDeviceWin( 297 BitmapPlatformDeviceWin::BitmapPlatformDeviceWin(
288 BitmapPlatformDeviceWinData* data, 298 BitmapPlatformDeviceWinData* data,
289 const SkBitmap& bitmap) : PlatformDeviceWin(bitmap), data_(data) { 299 const SkBitmap& bitmap)
300 : PlatformDeviceWin(bitmap),
301 data_(data) {
302 // The data object is already ref'ed for us by create().
290 } 303 }
291 304
292 // The copy constructor just adds another reference to the underlying data. 305 // The copy constructor just adds another reference to the underlying data.
293 // We use a const cast since the default Skia definitions don't define the 306 // We use a const cast since the default Skia definitions don't define the
294 // proper constedness that we expect (accessBitmap should really be const). 307 // proper constedness that we expect (accessBitmap should really be const).
295 BitmapPlatformDeviceWin::BitmapPlatformDeviceWin( 308 BitmapPlatformDeviceWin::BitmapPlatformDeviceWin(
296 const BitmapPlatformDeviceWin& other) 309 const BitmapPlatformDeviceWin& other)
297 : PlatformDeviceWin( 310 : PlatformDeviceWin(
298 const_cast<BitmapPlatformDeviceWin&>(other).accessBitmap(true)), 311 const_cast<BitmapPlatformDeviceWin&>(other).accessBitmap(true)),
299 data_(other.data_) { 312 data_(other.data_) {
313 data_->ref();
300 } 314 }
301 315
302 BitmapPlatformDeviceWin::~BitmapPlatformDeviceWin() { 316 BitmapPlatformDeviceWin::~BitmapPlatformDeviceWin() {
317 data_->unref();
303 } 318 }
304 319
305 BitmapPlatformDeviceWin& BitmapPlatformDeviceWin::operator=( 320 BitmapPlatformDeviceWin& BitmapPlatformDeviceWin::operator=(
306 const BitmapPlatformDeviceWin& other) { 321 const BitmapPlatformDeviceWin& other) {
307 data_ = other.data_; 322 data_ = other.data_;
323 data_->ref();
308 return *this; 324 return *this;
309 } 325 }
310 326
311 HDC BitmapPlatformDeviceWin::getBitmapDC() { 327 HDC BitmapPlatformDeviceWin::getBitmapDC() {
312 return data_->GetBitmapDC(); 328 return data_->GetBitmapDC();
313 } 329 }
314 330
315 void BitmapPlatformDeviceWin::setMatrixClip(const SkMatrix& transform, 331 void BitmapPlatformDeviceWin::setMatrixClip(const SkMatrix& transform,
316 const SkRegion& region) { 332 const SkRegion& region) {
317 data_->SetMatrixClip(transform, region); 333 data_->SetMatrixClip(transform, region);
318 } 334 }
319 335
320 void BitmapPlatformDeviceWin::drawToHDC(HDC dc, int x, int y, 336 void BitmapPlatformDeviceWin::drawToHDC(HDC dc, int x, int y,
321 const RECT* src_rect) { 337 const RECT* src_rect) {
322 bool created_dc = !data_->IsBitmapDCCreated(); 338 bool created_dc = !data_->IsBitmapDCCreated();
323 HDC source_dc = getBitmapDC(); 339 HDC source_dc = getBitmapDC();
324 340
325 RECT temp_rect; 341 RECT temp_rect;
326 if (!src_rect) { 342 if (!src_rect) {
327 temp_rect.left = 0; 343 temp_rect.left = 0;
328 temp_rect.right = width(); 344 temp_rect.right = width();
329 temp_rect.top = 0; 345 temp_rect.top = 0;
330 temp_rect.bottom = height(); 346 temp_rect.bottom = height();
331 src_rect = &temp_rect; 347 src_rect = &temp_rect;
(...skipping 12 matching lines...) Expand all
344 BitBlt(dc, 360 BitBlt(dc,
345 x, 361 x,
346 y, 362 y,
347 copy_width, 363 copy_width,
348 copy_height, 364 copy_height,
349 source_dc, 365 source_dc,
350 src_rect->left, 366 src_rect->left,
351 src_rect->top, 367 src_rect->top,
352 SRCCOPY); 368 SRCCOPY);
353 } else { 369 } else {
354 DCHECK(copy_width != 0 && copy_height != 0); 370 SkASSERT(copy_width != 0 && copy_height != 0);
355 BLENDFUNCTION blend_function = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA}; 371 BLENDFUNCTION blend_function = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
356 GdiAlphaBlend(dc, 372 GdiAlphaBlend(dc,
357 x, 373 x,
358 y, 374 y,
359 copy_width, 375 copy_width,
360 copy_height, 376 copy_height,
361 source_dc, 377 source_dc,
362 src_rect->left, 378 src_rect->left,
363 src_rect->top, 379 src_rect->top,
364 copy_width, 380 copy_width,
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 425
410 void BitmapPlatformDeviceWin::onAccessBitmap(SkBitmap* bitmap) { 426 void BitmapPlatformDeviceWin::onAccessBitmap(SkBitmap* bitmap) {
411 // FIXME(brettw) OPTIMIZATION: We should only flush if we know a GDI 427 // FIXME(brettw) OPTIMIZATION: We should only flush if we know a GDI
412 // operation has occurred on our DC. 428 // operation has occurred on our DC.
413 if (data_->IsBitmapDCCreated()) 429 if (data_->IsBitmapDCCreated())
414 GdiFlush(); 430 GdiFlush();
415 } 431 }
416 432
417 template<BitmapPlatformDeviceWin::adjustAlpha adjustor> 433 template<BitmapPlatformDeviceWin::adjustAlpha adjustor>
418 void BitmapPlatformDeviceWin::processPixels(int x, 434 void BitmapPlatformDeviceWin::processPixels(int x,
419 int y, 435 int y,
420 int width, 436 int width,
421 int height) { 437 int height) {
422 const SkBitmap& bitmap = accessBitmap(true); 438 const SkBitmap& bitmap = accessBitmap(true);
423 DCHECK_EQ(bitmap.config(), SkBitmap::kARGB_8888_Config); 439 SkASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config);
424 const SkMatrix& matrix = data_->transform(); 440 const SkMatrix& matrix = data_->transform();
425 int bitmap_start_x = SkScalarRound(matrix.getTranslateX()) + x; 441 int bitmap_start_x = SkScalarRound(matrix.getTranslateX()) + x;
426 int bitmap_start_y = SkScalarRound(matrix.getTranslateY()) + y; 442 int bitmap_start_y = SkScalarRound(matrix.getTranslateY()) + y;
427 443
428 if (Constrain(bitmap.width(), &bitmap_start_x, &width) && 444 if (Constrain(bitmap.width(), &bitmap_start_x, &width) &&
429 Constrain(bitmap.height(), &bitmap_start_y, &height)) { 445 Constrain(bitmap.height(), &bitmap_start_y, &height)) {
430 SkAutoLockPixels lock(bitmap); 446 SkAutoLockPixels lock(bitmap);
431 DCHECK_EQ(bitmap.rowBytes() % sizeof(uint32_t), 0u); 447 SkASSERT(bitmap.rowBytes() % sizeof(uint32_t) == 0u);
432 size_t row_words = bitmap.rowBytes() / sizeof(uint32_t); 448 size_t row_words = bitmap.rowBytes() / sizeof(uint32_t);
433 // Set data to the first pixel to be modified. 449 // Set data to the first pixel to be modified.
434 uint32_t* data = bitmap.getAddr32(0, 0) + (bitmap_start_y * row_words) + 450 uint32_t* data = bitmap.getAddr32(0, 0) + (bitmap_start_y * row_words) +
435 bitmap_start_x; 451 bitmap_start_x;
436 for (int i = 0; i < height; i++) { 452 for (int i = 0; i < height; i++) {
437 for (int j = 0; j < width; j++) { 453 for (int j = 0; j < width; j++) {
438 adjustor(data + j); 454 adjustor(data + j);
439 } 455 }
440 data += row_words; 456 data += row_words;
441 } 457 }
442 } 458 }
443 } 459 }
444 460
445 } // namespace skia 461 } // namespace skia
446 462
OLDNEW
« no previous file with comments | « skia/ext/bitmap_platform_device_win.h ('k') | skia/ext/platform_canvas_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698