| Index: skia/ext/raster_handle_allocator_win.cc
|
| diff --git a/skia/ext/raster_handle_allocator_win.cc b/skia/ext/raster_handle_allocator_win.cc
|
| index 22d9bf4b0e2d6f43a92d1ea5f42cb2ffca9e0444..fed059f89503e46b4f9bd904fc83a94d5da6169a 100644
|
| --- a/skia/ext/raster_handle_allocator_win.cc
|
| +++ b/skia/ext/raster_handle_allocator_win.cc
|
| @@ -19,23 +19,24 @@
|
|
|
| namespace {
|
|
|
| +struct HDCContextRec {
|
| + HDC hdc_;
|
| + HBITMAP prev_bitmap_;
|
| +};
|
| +
|
| static void DeleteHDCCallback(void*, void* context) {
|
| DCHECK_NE(context, nullptr);
|
| - HDC hdc = static_cast<HDC>(context);
|
| -
|
| - // We must get this before we call RestoreDC, as that will drop hbitmap and
|
| - // reselect the original/default bitmap.
|
| - HGDIOBJ hbitmap = GetCurrentObject(hdc, OBJ_BITMAP);
|
| - DCHECK_NE(hbitmap, nullptr);
|
| + const HDCContextRec* rec = static_cast<const HDCContextRec*>(context);
|
|
|
| - bool success = RestoreDC(hdc, -1); // effectly performs the deselect of hbitmap
|
| + // Must select back in the old bitmap before we delete the hdc, and so we can
|
| + // recover the new_bitmap that we allocated, so we can delete it.
|
| + HBITMAP new_bitmap =
|
| + static_cast<HBITMAP>(SelectObject(rec->hdc_, rec->prev_bitmap_));
|
| + bool success = DeleteObject(new_bitmap);
|
| DCHECK(success);
|
| -
|
| - // Now we are the only owner, so we can delete our bitmap
|
| - success = DeleteObject(hbitmap);
|
| - DCHECK(success);
|
| - success = DeleteDC(hdc);
|
| + success = DeleteDC(rec->hdc_);
|
| DCHECK(success);
|
| + delete rec;
|
| }
|
|
|
| // Allocate the layer and fill in the fields for the Rec, or return false
|
| @@ -47,9 +48,9 @@ static bool Create(int width,
|
| bool do_clear,
|
| SkRasterHandleAllocator::Rec* rec) {
|
| void* pixels;
|
| - HBITMAP hbitmap =
|
| + HBITMAP new_bitmap =
|
| skia::CreateHBitmap(width, height, is_opaque, shared_section, &pixels);
|
| - if (!hbitmap) {
|
| + if (!new_bitmap) {
|
| LOG(ERROR) << "CreateHBitmap failed";
|
| return false;
|
| }
|
| @@ -60,21 +61,16 @@ static bool Create(int width,
|
|
|
| HDC hdc = CreateCompatibleDC(nullptr);
|
| if (!hdc) {
|
| - DeleteObject(hbitmap);
|
| + DeleteObject(new_bitmap);
|
| return false;
|
| }
|
| SetGraphicsMode(hdc, GM_ADVANCED);
|
|
|
| - int saveIndex = SaveDC(hdc); // so we can Restore in the delete callback
|
| - DCHECK_NE(saveIndex, 0);
|
| -
|
| - // Be sure to select *after* we called SaveDC.
|
| - // Because we're using save/restore, we don't need to explicitly track the
|
| - // returned "previous" value.
|
| - SelectObject(hdc, hbitmap);
|
| + HBITMAP prev_bitmap = static_cast<HBITMAP>(SelectObject(hdc, new_bitmap));
|
| + DCHECK(prev_bitmap);
|
|
|
| rec->fReleaseProc = DeleteHDCCallback;
|
| - rec->fReleaseCtx = hdc;
|
| + rec->fReleaseCtx = new HDCContextRec{hdc, prev_bitmap};
|
| rec->fPixels = pixels;
|
| rec->fRowBytes = row_bytes;
|
| rec->fHandle = hdc;
|
|
|