OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include <windows.h> | |
6 #include <psapi.h> | |
7 #include <stddef.h> | |
8 | |
9 #include "base/debug/gdi_debug_util_win.h" | |
10 #include "base/logging.h" | |
11 #include "base/win/win_util.h" | |
12 #include "skia/ext/bitmap_platform_device_win.h" | |
13 #include "skia/ext/platform_canvas.h" | |
14 #include "skia/ext/skia_utils_win.h" | |
15 #include "third_party/skia/include/core/SkMatrix.h" | |
16 #include "third_party/skia/include/core/SkPath.h" | |
17 #include "third_party/skia/include/core/SkRefCnt.h" | |
18 #include "third_party/skia/include/core/SkRect.h" | |
19 | |
20 namespace { | |
21 | |
22 static void DeleteHDCCallback(void*, void* context) { | |
23 HDC hdc = static_cast<HDC>(context); | |
24 HBITMAP hbitmap = static_cast<HBITMAP> SelectObject(hdc, nullptr); | |
25 DeleteObject(hbitmap); | |
26 DeleteDC(hdc); | |
27 } | |
28 | |
29 // We use this static factory function instead of the regular constructor so | |
30 // that we can create the pixel data before calling the constructor. This is | |
31 // required so that we can call the base class' constructor with the pixel | |
32 // data. | |
33 static bool Create(int width, | |
34 int height, | |
35 bool is_opaque, | |
36 HANDLE shared_section, | |
37 bool do_clear, | |
38 SkRasterHandleAllocator::Rec* rec) { | |
39 void* pixels; | |
40 HBITMAP hbitmap = | |
41 skia::CreateHBitmap(width, height, is_opaque, shared_section, &data); | |
f(malita)
2017/01/10 16:10:15
s/data/pixels?
| |
42 if (!hbitmap) { | |
43 LOG(ERROR) << "CreateHBitmap failed"; | |
44 return false; | |
45 } | |
46 | |
47 size_t row_bytes = PlatformCanvasStrideForWidth(width); | |
48 if (do_clear) | |
49 sk_bzero(pixels, row_bytes * height); | |
50 | |
51 HDC hdc = CreateCompatibleDC(nullptr); | |
52 if (!hdc) { | |
53 DeleteObject(hbitmap); | |
54 return false; | |
55 } | |
56 SelectObject(hdc, hbitmap); | |
57 | |
58 rec->fReleaseProc = DeleteHDCCallback; | |
59 rec->fReleaseCtx = hdc; | |
60 rec->fPixels = pixels; | |
61 rec->fRowBytes = row_bytes; | |
62 rec->fHandle = hdc; | |
63 return true; | |
64 } | |
65 | |
66 /** | |
67 * Subclass of SkRasterHandleAllocator that returns an HDC as its "handle". | |
68 */ | |
69 class GDIAllocator : public SkRasterHandleAllocator { | |
70 public: | |
71 GDIAllocator() {} | |
72 | |
73 bool allocHandle(const SkImageInfo& info, Rec* rec) override { | |
74 SkASSERT(info.colorType() == kN32_SkColorType); | |
75 return Create(info.width(), info.height(), info.isOpaque(), nullptr, | |
76 !info.isOpaque(), rec); | |
77 } | |
78 | |
79 void updateHandle(Handle handle, | |
80 const SkMatrix& ctm, | |
81 const SkIRect& clip_bounds) override { | |
82 HDC hdc = static_cast<HDC>(handle); | |
83 | |
84 skia::LoadTransformToDC(hdc, ctm); | |
85 | |
86 HRGN hrgn = CreateRectRgnIndirect(&skia::SkIRectToRECT(clip_bounds)); | |
87 int result = SelectClipRgn(hdc, hrgn); | |
88 DCHECK(result != ERROR); | |
89 result = DeleteObject(hrgn); | |
90 DCHECK(result != 0); | |
91 } | |
92 }; | |
93 | |
94 } // namespace | |
95 | |
96 namespace skia { | |
97 | |
98 std::unique_ptr<SkCanvas> CreatePlatformCanvasWithSharedSection( | |
99 int width, | |
100 int height, | |
101 bool is_opaque, | |
102 HANDLE shared_section, | |
103 OnFailureType failure_type) { | |
104 SkAlphaType alpha = is_opaque ? kPremul_SkAlphaType : kOpaque_SkAlphaType; | |
105 SkImageInfo info = SkImageInfo::MakeN32(width, height, alpha); | |
106 size_t row_bytes = PlatformCanvasStrideForWidth(width); | |
107 | |
108 // This function contains an implementation of a Skia platform bitmap for | |
109 // drawing and compositing graphics. The original implementation uses Windows | |
110 // GDI to create the backing bitmap memory, however it's possible for a | |
111 // process to not have access to GDI which will cause this code to fail. It's | |
112 // possible to detect when GDI is unavailable and instead directly map the | |
113 // shared memory as the bitmap. | |
114 if (base::win::IsUser32AndGdi32Available()) { | |
115 SkRasterHandleAllocator::Rec rec; | |
116 if (Create(width, height, is_opaque, shared_section, false, &rec)) | |
117 return SkRasterHandleAllocator::MakeCanvas( | |
118 std::unique_ptr<SkRasterHandleAllocator>(new GDIAllocator), info, | |
119 &rec); | |
120 } else { | |
121 DCHECK(shared_section != NULL); | |
122 void* pixels = | |
123 MapViewOfFile(shared_section, FILE_MAP_WRITE, 0, 0, row_bytes * height); | |
124 if (pixels) | |
125 return SkCanvas::MakeRasterDirect(info, pixels, row_bytes); | |
126 } | |
127 | |
128 if (failure_type == CRASH_ON_FAILURE) | |
129 SK_CRASH(); | |
130 return nullptr; | |
131 } | |
132 | |
133 } // namespace skia | |
OLD | NEW |