Index: skia/ext/layer_allocator_win.cc |
diff --git a/skia/ext/layer_allocator_win.cc b/skia/ext/layer_allocator_win.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..b9a83210ffdde733590de54a01204c9da94eded7 |
--- /dev/null |
+++ b/skia/ext/layer_allocator_win.cc |
@@ -0,0 +1,105 @@ |
+// Copyright 2016 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 "build/build_config.h" |
+#include "skia/ext/layer_allocator_win.h" |
+#include "third_party/skia/include/core/SkMatrix.h" |
+#include "third_party/skia/include/core/SkRect.h" |
+ |
+namespace { |
+ |
+void LoadClippingRegionToDC(HDC context, |
+ const SkMatrix& transformation, |
+ const SkIRect& clip_bounds) { |
+ HRGN hrgn = CreateRectRgnIndirect(&skia::SkIRectToRECT(clip_bounds)); |
+ int result = SelectClipRgn(context, hrgn); |
+ SkASSERT(result != ERROR); |
+ result = DeleteObject(hrgn); |
+ SkASSERT(result != 0); |
+} |
+ |
+// Old implementation restored the previously-selected bitmap |
+// but it's not clear whether that is necessary. |
+void FreeWindowsBacking(void* context) { |
+ if (!context) |
+ return; |
+ HBITMAP bitmap; |
+ bitmap = SelectObject(hbitmap, nullptr); |
+ DeleteObject(hbitmap); |
+ DeleteObject(context); |
+} |
+ |
+} // namespace |
+ |
+namespace skia { |
+ |
+LayerAllocator::LayerAllocator() { } |
+ |
+LayerAllocator::~LayerAllocator() { } |
+ |
+void* LayerAllocator::getNativeContext(void* buffer, |
+ const SkMatrix& transform, |
+ const SkIRect& clip_bounds) { |
+ if (!buffer) |
+ return nullptr; |
+ |
+ context_map_t::iterator it = contexts_.find(buffer); |
+ if (it == contexts_.end()) |
+ return nullptr; |
+ |
+ skia::LoadTransformToDC(it->second, transform); |
+ LoadClippingRegionToDC(it->second, transform, clip_bounds); |
+ |
+ // This is where we should flush the bitmap & mark it dirty, |
+ // but the old implementation didn't seem to do so. |
+ |
+ return it->second; |
+} |
+ |
+void* LayerAllocator::allocateLayer(const SkImageInfo& info, |
+ size_t* rowBytes, |
+ void (**deallocator)(void*), |
+ void** deallocatorPayload, |
+ void* initialData) { |
+ SkASSERT(info.colorType() == kN32_SkColorType); |
+ |
+ void* buffer = nullptr; |
+ HDC context = nullptr; |
+ |
+/* |
+ cairo_surface_t* surface; |
+ if (initialData) |
+ surface = cairo_image_surface_create_for_data( |
+ (unsigned char*) initialData, |
+ CAIRO_FORMAT_ARGB32, |
+ info.width(), |
+ info.height(), |
+ cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, info.width())); |
+ else |
+ surface = cairo_image_surface_create( |
+ CAIRO_FORMAT_ARGB32, info.width(), info.height()); |
+ if (!surface) |
+ return nullptr; |
+ |
+ if (rowBytes) |
+ *rowBytes = cairo_image_surface_get_stride(surface); |
+ |
+ cairo_t* context = cairo_create(surface); |
+ if (!context) { |
+ cairo_surface_destroy(surface); |
+ return nullptr; |
+ } |
+ void* buffer = cairo_image_surface_get_data(surface); |
+*/ |
+ |
+ contexts_.insert({buffer, context}); |
+ |
+ *deallocator = FreeWindowsBacking; |
+ *deallocatorPayload = context; |
+ |
+ return buffer; |
+} |
+ |
+} // namespace skia |
+ |