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

Unified Diff: skia/ext/raster_handle_allocator_win.cc

Issue 2736743002: don't rely on save/restore for the selected bitmap (Closed)
Patch Set: no need to store new bitmap Created 3 years, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
« 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