OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 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 "ui/gfx/surface/transport_dib.h" | |
6 | |
7 #include <windows.h> | |
8 | |
9 #include <limits> | |
10 | |
11 #include "base/logging.h" | |
12 #include "base/memory/scoped_ptr.h" | |
13 #include "base/sys_info.h" | |
14 #include "skia/ext/platform_canvas.h" | |
15 | |
16 TransportDIB::TransportDIB() { | |
17 } | |
18 | |
19 TransportDIB::~TransportDIB() { | |
20 } | |
21 | |
22 TransportDIB::TransportDIB(HANDLE handle) | |
23 : shared_memory_(handle, false /* read write */) { | |
24 } | |
25 | |
26 // static | |
27 TransportDIB* TransportDIB::Create(size_t size, uint32 sequence_num) { | |
28 size_t allocation_granularity = base::SysInfo::VMAllocationGranularity(); | |
29 size = size / allocation_granularity + 1; | |
30 size = size * allocation_granularity; | |
31 | |
32 TransportDIB* dib = new TransportDIB; | |
33 | |
34 if (!dib->shared_memory_.CreateAnonymous(size)) { | |
35 delete dib; | |
36 return NULL; | |
37 } | |
38 | |
39 dib->size_ = size; | |
40 dib->sequence_num_ = sequence_num; | |
41 | |
42 return dib; | |
43 } | |
44 | |
45 // static | |
46 TransportDIB* TransportDIB::Map(Handle handle) { | |
47 scoped_ptr<TransportDIB> dib(CreateWithHandle(handle)); | |
48 if (!dib->Map()) | |
49 return NULL; | |
50 return dib.release(); | |
51 } | |
52 | |
53 // static | |
54 TransportDIB* TransportDIB::CreateWithHandle(Handle handle) { | |
55 return new TransportDIB(handle); | |
56 } | |
57 | |
58 // static | |
59 bool TransportDIB::is_valid_handle(Handle dib) { | |
60 return dib != NULL; | |
61 } | |
62 | |
63 // static | |
64 bool TransportDIB::is_valid_id(TransportDIB::Id id) { | |
65 return is_valid_handle(id.handle); | |
66 } | |
67 | |
68 skia::PlatformCanvas* TransportDIB::GetPlatformCanvas(int w, int h) { | |
69 // This DIB already mapped the file into this process, but PlatformCanvas | |
70 // will map it again. | |
71 DCHECK(!memory()) << "Mapped file twice in the same process."; | |
72 | |
73 scoped_ptr<skia::PlatformCanvas> canvas(new skia::PlatformCanvas); | |
74 if (!canvas->initialize(w, h, true, handle())) | |
75 return NULL; | |
76 return canvas.release(); | |
77 } | |
78 | |
79 bool TransportDIB::Map() { | |
80 if (!is_valid_handle(handle())) | |
81 return false; | |
82 if (memory()) | |
83 return true; | |
84 | |
85 if (!shared_memory_.Map(0 /* map whole shared memory segment */)) { | |
86 LOG(ERROR) << "Failed to map transport DIB" | |
87 << " handle:" << shared_memory_.handle() | |
88 << " error:" << ::GetLastError(); | |
89 return false; | |
90 } | |
91 | |
92 // There doesn't seem to be any way to find the size of the shared memory | |
93 // region! GetFileSize indicates that the handle is invalid. Thus, we | |
94 // conservatively set the size to the maximum and hope that the renderer | |
95 // isn't about to ask us to read off the end of the array. | |
96 size_ = std::numeric_limits<size_t>::max(); | |
97 return true; | |
98 } | |
99 | |
100 void* TransportDIB::memory() const { | |
101 return shared_memory_.memory(); | |
102 } | |
103 | |
104 TransportDIB::Handle TransportDIB::handle() const { | |
105 return shared_memory_.handle(); | |
106 } | |
107 | |
108 TransportDIB::Id TransportDIB::id() const { | |
109 return Id(handle(), sequence_num_); | |
110 } | |
OLD | NEW |