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 |
new file mode 100644 |
index 0000000000000000000000000000000000000000..cda8a7ba71e4e4fb8519ed87beab06856a7b38a4 |
--- /dev/null |
+++ b/skia/ext/raster_handle_allocator_win.cc |
@@ -0,0 +1,133 @@ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include <windows.h> |
+#include <psapi.h> |
+#include <stddef.h> |
+ |
+#include "base/debug/gdi_debug_util_win.h" |
+#include "base/logging.h" |
+#include "base/win/win_util.h" |
+#include "skia/ext/bitmap_platform_device_win.h" |
+#include "skia/ext/platform_canvas.h" |
+#include "skia/ext/skia_utils_win.h" |
+#include "third_party/skia/include/core/SkMatrix.h" |
+#include "third_party/skia/include/core/SkPath.h" |
+#include "third_party/skia/include/core/SkRefCnt.h" |
+#include "third_party/skia/include/core/SkRect.h" |
+ |
+namespace { |
+ |
+static void DeleteHDCCallback(void*, void* context) { |
+ HDC hdc = static_cast<HDC>(context); |
+ HBITMAP hbitmap = static_cast<HBITMAP> SelectObject(hdc, nullptr); |
+ DeleteObject(hbitmap); |
+ DeleteDC(hdc); |
+} |
+ |
+// We use this static factory function instead of the regular constructor so |
+// that we can create the pixel data before calling the constructor. This is |
+// required so that we can call the base class' constructor with the pixel |
+// data. |
+static bool Create(int width, |
+ int height, |
+ bool is_opaque, |
+ HANDLE shared_section, |
+ bool do_clear, |
+ SkRasterHandleAllocator::Rec* rec) { |
+ void* pixels; |
+ HBITMAP hbitmap = |
+ skia::CreateHBitmap(width, height, is_opaque, shared_section, &data); |
f(malita)
2017/01/10 16:10:15
s/data/pixels?
|
+ if (!hbitmap) { |
+ LOG(ERROR) << "CreateHBitmap failed"; |
+ return false; |
+ } |
+ |
+ size_t row_bytes = PlatformCanvasStrideForWidth(width); |
+ if (do_clear) |
+ sk_bzero(pixels, row_bytes * height); |
+ |
+ HDC hdc = CreateCompatibleDC(nullptr); |
+ if (!hdc) { |
+ DeleteObject(hbitmap); |
+ return false; |
+ } |
+ SelectObject(hdc, hbitmap); |
+ |
+ rec->fReleaseProc = DeleteHDCCallback; |
+ rec->fReleaseCtx = hdc; |
+ rec->fPixels = pixels; |
+ rec->fRowBytes = row_bytes; |
+ rec->fHandle = hdc; |
+ return true; |
+} |
+ |
+/** |
+ * Subclass of SkRasterHandleAllocator that returns an HDC as its "handle". |
+ */ |
+class GDIAllocator : public SkRasterHandleAllocator { |
+ public: |
+ GDIAllocator() {} |
+ |
+ bool allocHandle(const SkImageInfo& info, Rec* rec) override { |
+ SkASSERT(info.colorType() == kN32_SkColorType); |
+ return Create(info.width(), info.height(), info.isOpaque(), nullptr, |
+ !info.isOpaque(), rec); |
+ } |
+ |
+ void updateHandle(Handle handle, |
+ const SkMatrix& ctm, |
+ const SkIRect& clip_bounds) override { |
+ HDC hdc = static_cast<HDC>(handle); |
+ |
+ skia::LoadTransformToDC(hdc, ctm); |
+ |
+ HRGN hrgn = CreateRectRgnIndirect(&skia::SkIRectToRECT(clip_bounds)); |
+ int result = SelectClipRgn(hdc, hrgn); |
+ DCHECK(result != ERROR); |
+ result = DeleteObject(hrgn); |
+ DCHECK(result != 0); |
+ } |
+}; |
+ |
+} // namespace |
+ |
+namespace skia { |
+ |
+std::unique_ptr<SkCanvas> CreatePlatformCanvasWithSharedSection( |
+ int width, |
+ int height, |
+ bool is_opaque, |
+ HANDLE shared_section, |
+ OnFailureType failure_type) { |
+ SkAlphaType alpha = is_opaque ? kPremul_SkAlphaType : kOpaque_SkAlphaType; |
+ SkImageInfo info = SkImageInfo::MakeN32(width, height, alpha); |
+ size_t row_bytes = PlatformCanvasStrideForWidth(width); |
+ |
+ // This function contains an implementation of a Skia platform bitmap for |
+ // drawing and compositing graphics. The original implementation uses Windows |
+ // GDI to create the backing bitmap memory, however it's possible for a |
+ // process to not have access to GDI which will cause this code to fail. It's |
+ // possible to detect when GDI is unavailable and instead directly map the |
+ // shared memory as the bitmap. |
+ if (base::win::IsUser32AndGdi32Available()) { |
+ SkRasterHandleAllocator::Rec rec; |
+ if (Create(width, height, is_opaque, shared_section, false, &rec)) |
+ return SkRasterHandleAllocator::MakeCanvas( |
+ std::unique_ptr<SkRasterHandleAllocator>(new GDIAllocator), info, |
+ &rec); |
+ } else { |
+ DCHECK(shared_section != NULL); |
+ void* pixels = |
+ MapViewOfFile(shared_section, FILE_MAP_WRITE, 0, 0, row_bytes * height); |
+ if (pixels) |
+ return SkCanvas::MakeRasterDirect(info, pixels, row_bytes); |
+ } |
+ |
+ if (failure_type == CRASH_ON_FAILURE) |
+ SK_CRASH(); |
+ return nullptr; |
+} |
+ |
+} // namespace skia |