Index: skia/ext/skia_utils_win.cc |
diff --git a/skia/ext/skia_utils_win.cc b/skia/ext/skia_utils_win.cc |
index 9873373725705fe6f8e4491a54ebd56916829276..c53bb3e35838a22e3018acbceaaa7b67236c56a0 100644 |
--- a/skia/ext/skia_utils_win.cc |
+++ b/skia/ext/skia_utils_win.cc |
@@ -7,7 +7,10 @@ |
#include <stddef.h> |
#include <windows.h> |
+#include "base/debug/gdi_debug_util_win.h" |
+#include "base/win/win_util.h" |
#include "third_party/skia/include/core/SkRect.h" |
+#include "third_party/skia/include/core/SkSurface.h" |
#include "third_party/skia/include/core/SkTypes.h" |
#include "third_party/skia/include/effects/SkGradientShader.h" |
@@ -23,8 +26,42 @@ static_assert(sizeof(RECT().right) == sizeof(SkIRect().fRight), "o7"); |
static_assert(sizeof(RECT().bottom) == sizeof(SkIRect().fBottom), "o8"); |
static_assert(sizeof(RECT) == sizeof(SkIRect), "o9"); |
-} // namespace |
+HBITMAP CreateHBitmap(int width, int height) { |
+ // CreateDIBSection appears to get unhappy if we create an empty bitmap, so |
+ // just create a minimal bitmap. |
+ if ((width == 0) || (height == 0)) { |
+ width = 1; |
+ height = 1; |
+ } |
+ |
+ BITMAPINFOHEADER hdr = {0}; |
+ hdr.biSize = sizeof(BITMAPINFOHEADER); |
+ hdr.biWidth = width; |
+ hdr.biHeight = -height; // minus means top-down bitmap |
+ hdr.biPlanes = 1; |
+ hdr.biBitCount = 32; |
+ hdr.biCompression = BI_RGB; // no compression |
+ hdr.biSizeImage = 0; |
+ hdr.biXPelsPerMeter = 1; |
+ hdr.biYPelsPerMeter = 1; |
+ hdr.biClrUsed = 0; |
+ hdr.biClrImportant = 0; |
+ |
+ HBITMAP hbitmap = CreateDIBSection(nullptr, reinterpret_cast<BITMAPINFO*>(&hdr), |
Peter Kasting
2016/02/16 21:12:10
Nit: 80 columns
tomhudson
2016/06/21 22:20:22
Done.
|
+ 0, nullptr, nullptr, 0); |
+ |
+#if !defined(_WIN64) |
+ // If CreateDIBSection() failed, try to get some useful |
Peter Kasting
2016/02/16 21:12:10
Nit: Wrap as late as possible
tomhudson
2016/06/21 22:20:22
Done.
|
+ // information out before we crash for post-mortem analysis. |
+ if (!hbitmap) |
+ base::debug::GDIBitmapAllocFailure(&hdr, nullptr); |
+#endif |
+ |
+ return hbitmap; |
+} |
+ |
+} // namespace |
namespace skia { |
POINT SkPointToPOINT(const SkPoint& point) { |
@@ -73,7 +110,7 @@ void InitializeDC(HDC context) { |
SkASSERT(res != 0); |
// As per SetStretchBltMode() documentation, SetBrushOrgEx() must be called |
// right after. |
- res = SetBrushOrgEx(context, 0, 0, NULL); |
+ res = SetBrushOrgEx(context, 0, 0, nullptr); |
SkASSERT(res != 0); |
// Sets up default orientation. |
@@ -97,5 +134,94 @@ void InitializeDC(HDC context) { |
SkASSERT(res != 0); |
} |
+#if 0 |
+namespace { |
+ |
+bool PrepareAllocation(HDC context, SkImageInfo* size, BITMAP* backing) { |
+ HBITMAP backing_handle = |
+ static_cast<HBITMAP>(GetCurrentObject(context, OBJ_BITMAP)); |
+ if (GetObject(backing_handle, sizeof(*backing), |
+ backing) != sizeof(*backing)) |
+ return false; |
+ *size = SkImageInfo::MakeN32Premul(backing->bmWidth, |
+ backing->bmHeight); |
+ return true; |
+} |
+ |
+} |
+ |
+SkSurface* MapPlatformSurface(HDC context) { |
+ SkImageInfo size; |
+ Bitmap backing; |
+ if (!PrepareAllocation(HDC, &size, &backing)) |
+ return nullptr; |
+ return SkSurface::NewRasterDirect(size, backing.bmBits, |
+ backing.bmWidthBytes); |
+} |
+ |
+SkBitmap MapPlatformBitmap(HDC context) { |
+ SkImageInfo size; |
+ Bitmap backing; |
+ SkBitmap bitmap; |
+ if (PrepareAllocation(HDC, &size, &backing)) |
+ bitmap.installPixels(size, backing.bmBits, size.minRowBytes()); |
+ return bitmap; |
+} |
+#endif |
+ |
+SkSurface* MapPlatformSurface(HDC context) { |
+ HBITMAP backing_handle = |
+ static_cast<HBITMAP>(GetCurrentObject(context, OBJ_BITMAP)); |
+ BITMAP backing; |
+ if (GetObject(backing_handle, sizeof(backing), |
+ &backing) != sizeof(backing)) |
+ return nullptr; |
+ return SkSurface::NewRasterDirect( |
+ SkImageInfo::MakeN32Premul(backing.bmWidth, backing.bmHeight), |
+ backing.bmBits, backing.bmWidthBytes); |
+} |
+ |
+SkBitmap MapPlatformBitmap(HDC context) { |
+ HBITMAP backing_handle = |
+ static_cast<HBITMAP>(GetCurrentObject(context, OBJ_BITMAP)); |
+ BITMAP backing; |
+ SkBitmap bitmap; |
+ if (GetObject(backing_handle, sizeof(backing), |
+ &backing) == sizeof(backing)) { |
+ SkImageInfo size = SkImageInfo::MakeN32Premul(backing.bmWidth, |
+ backing.bmHeight); |
+ bitmap.installPixels(size, backing.bmBits, size.minRowBytes()); |
+ } |
+ return bitmap; |
+} |
+ |
+HDC CreateOffscreenSurface(int width, int height) { |
+ HBITMAP bitmap = nullptr; |
+ |
+ // If this process doesn't have access to GDI, we'll have to use a shared |
+ // memory segment instead. |
+ if (!base::win::IsUser32AndGdi32Available()) |
+ return nullptr; |
+ |
+ bitmap = CreateHBitmap(width, height); |
+ if (!bitmap) |
+ return nullptr; |
+ |
+ HDC hdc = CreateCompatibleDC(nullptr); |
+ SkASSERT(hdc); |
+ InitializeDC(hdc); |
+ HRGN clip = CreateRectRgn(0, 0, width, height); |
+ int result = SelectClipRgn(hdc, clip); |
+ SkASSERT(result != ERROR); |
+ result = DeleteObject(clip); |
+ SkASSERT(result); |
+ |
+ SelectObject(hdc, bitmap); |
+ |
+ // need to clean up by calling DeleteDC(hdc) else we leak! |
+ |
+ return hdc; |
+} |
+ |
} // namespace skia |