OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 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 "content/child/child_io_surface_manager_mac.h" | |
6 | |
7 #include <bsm/libbsm.h> | |
Robert Sesek
2015/05/15 21:45:05
Unused.
reveman
2015/05/18 18:15:38
Done.
| |
8 #include <servers/bootstrap.h> | |
9 | |
10 #include <string> | |
11 | |
12 #include "base/logging.h" | |
13 #include "base/mac/foundation_util.h" | |
14 #include "base/mac/mach_logging.h" | |
15 #include "base/strings/stringprintf.h" | |
16 #include "content/common/mac/io_surface_manager_messages.h" | |
17 | |
18 namespace content { | |
19 | |
20 // static | |
21 ChildIOSurfaceManager* ChildIOSurfaceManager::GetInstance() { | |
22 return Singleton<ChildIOSurfaceManager, | |
23 LeakySingletonTraits<ChildIOSurfaceManager>>::get(); | |
24 } | |
25 | |
26 bool ChildIOSurfaceManager::RegisterIOSurface(int io_surface_id, | |
27 int client_id, | |
28 IOSurfaceRef io_surface) { | |
29 // Deallocate the right after sending a copy to the parent. | |
30 base::mac::ScopedMachSendRight scoped_io_surface_right( | |
Robert Sesek
2015/05/15 21:45:05
Do this after allocating the reply, since that can
reveman
2015/05/18 18:15:38
Good call. Done.
| |
31 IOSurfaceCreateMachPort(io_surface)); | |
32 | |
33 mach_port_t receive_port; | |
Robert Sesek
2015/05/15 21:45:05
naming: reply_port
reveman
2015/05/18 18:15:39
Done.
| |
34 kern_return_t kr = mach_port_allocate(mach_task_self(), | |
35 MACH_PORT_RIGHT_RECEIVE, &receive_port); | |
36 if (kr != KERN_SUCCESS) { | |
37 MACH_LOG(ERROR, kr) << "mach_port_allocate"; | |
38 return false; | |
39 } | |
40 base::mac::ScopedMachReceiveRight scoped_receive_right(receive_port); | |
41 | |
42 union { | |
Robert Sesek
2015/05/15 21:45:05
I'd avoid a union here.
reveman
2015/05/18 18:15:39
hm, how? by using mach_msg_overwrite?
Robert Sesek
2015/05/19 23:26:23
No, just declare two variables not in a union.
| |
43 struct { | |
44 mach_msg_header_t header; | |
45 mach_msg_body_t body; | |
46 IOSurfaceManagerHostMsg_RegisterIOSurface msg; | |
47 gpu::Mailbox mailbox; | |
48 } request; | |
49 struct { | |
50 mach_msg_header_t header; | |
51 mach_msg_body_t body; | |
52 IOSurfaceManagerMsg_RegisterIOSurfaceReply msg; | |
53 mach_msg_trailer_t trailer; | |
54 } reply; | |
55 } data = {{{0}}}; | |
56 data.request.header.msgh_bits = | |
57 MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE) | | |
58 MACH_MSGH_BITS_COMPLEX; | |
59 data.request.header.msgh_remote_port = send_port_; | |
60 data.request.header.msgh_local_port = receive_port; | |
61 data.request.header.msgh_size = sizeof(data.request); | |
62 data.request.header.msgh_id = IOSurfaceManagerHostMsg_RegisterIOSurface::ID; | |
63 data.request.body.msgh_descriptor_count = 1; | |
64 data.request.msg.io_surface_port.name = scoped_io_surface_right; | |
65 data.request.msg.io_surface_port.disposition = MACH_MSG_TYPE_COPY_SEND; | |
66 data.request.msg.io_surface_port.type = MACH_MSG_PORT_DESCRIPTOR; | |
67 data.request.msg.io_surface_id = io_surface_id; | |
68 data.request.msg.client_id = client_id; | |
69 data.request.mailbox = mailbox_; | |
70 | |
71 kr = mach_msg(&data.request.header, MACH_SEND_MSG | MACH_RCV_MSG, | |
72 sizeof(data.request), sizeof(data.reply), receive_port, | |
73 MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); | |
74 if (kr != KERN_SUCCESS) { | |
75 MACH_LOG(ERROR, kr) << "mach_msg"; | |
76 return false; | |
77 } | |
78 | |
79 return data.reply.msg.result; | |
80 } | |
81 | |
82 void ChildIOSurfaceManager::UnregisterIOSurface(int io_surface_id, | |
83 int client_id) { | |
84 struct { | |
85 mach_msg_header_t header; | |
86 mach_msg_body_t body; | |
87 IOSurfaceManagerHostMsg_UnregisterIOSurface msg; | |
88 gpu::Mailbox mailbox; | |
89 } request = {{0}}; | |
90 | |
91 request.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0); | |
92 request.header.msgh_remote_port = send_port_; | |
93 request.header.msgh_local_port = MACH_PORT_NULL; | |
94 request.header.msgh_size = sizeof(request); | |
95 request.header.msgh_id = IOSurfaceManagerHostMsg_UnregisterIOSurface::ID; | |
96 request.msg.io_surface_id = io_surface_id; | |
97 request.msg.client_id = client_id; | |
98 request.mailbox = mailbox_; | |
99 | |
100 kern_return_t kr = mach_msg( | |
101 &request.header, MACH_SEND_MSG | MACH_SEND_TIMEOUT, sizeof(request), 0, | |
102 MACH_PORT_NULL, 100 /*milliseconds*/, MACH_PORT_NULL); | |
103 if (kr != KERN_SUCCESS) { | |
104 MACH_LOG(ERROR, kr) << "mach_msg"; | |
105 } | |
106 } | |
107 | |
108 IOSurfaceRef ChildIOSurfaceManager::AcquireIOSurface(int io_surface_id) { | |
109 mach_port_t receive_port; | |
110 kern_return_t kr = mach_port_allocate(mach_task_self(), | |
111 MACH_PORT_RIGHT_RECEIVE, &receive_port); | |
112 if (kr != KERN_SUCCESS) { | |
113 MACH_LOG(ERROR, kr) << "mach_port_allocate"; | |
114 return nullptr; | |
115 } | |
116 base::mac::ScopedMachReceiveRight scoped_receive_right(receive_port); | |
117 | |
118 union { | |
119 struct { | |
120 mach_msg_header_t header; | |
121 mach_msg_body_t body; | |
122 IOSurfaceManagerHostMsg_AcquireIOSurface msg; | |
123 gpu::Mailbox mailbox; | |
124 } request; | |
125 struct { | |
126 mach_msg_header_t header; | |
127 mach_msg_body_t body; | |
128 IOSurfaceManagerMsg_AcquireIOSurfaceReply msg; | |
129 mach_msg_trailer_t trailer; | |
130 } reply; | |
131 } data = {{{0}}}; | |
132 data.request.header.msgh_bits = | |
133 MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE); | |
134 data.request.header.msgh_remote_port = send_port_; | |
135 data.request.header.msgh_local_port = receive_port; | |
136 data.request.header.msgh_size = sizeof(data.request); | |
137 data.request.header.msgh_id = IOSurfaceManagerHostMsg_AcquireIOSurface::ID; | |
138 data.request.msg.io_surface_id = io_surface_id; | |
139 data.request.mailbox = mailbox_; | |
140 | |
141 kr = mach_msg(&data.request.header, MACH_SEND_MSG | MACH_RCV_MSG, | |
142 sizeof(data.request), sizeof(data.reply), receive_port, | |
143 MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); | |
144 if (kr != KERN_SUCCESS) { | |
145 MACH_LOG(ERROR, kr) << "mach_msg"; | |
146 return nullptr; | |
147 } | |
148 | |
149 return IOSurfaceLookupFromMachPort(data.reply.msg.io_surface_port.name); | |
150 } | |
151 | |
152 ChildIOSurfaceManager::ChildIOSurfaceManager() : send_port_(MACH_PORT_NULL) { | |
153 // Look up the named IOSurfaceManager port that's been registered with | |
154 // the bootstrap server. | |
155 std::string mach_port_name = base::StringPrintf( | |
156 "%s.iosurfacemgr.%d", base::mac::BaseBundleID(), getppid()); | |
Robert Sesek
2015/05/15 21:45:05
This could be centralized to IOSurfaceManager as a
reveman
2015/05/18 18:15:38
Done. See LookupServicePort in latest patch.
| |
157 mach_port_t port; | |
158 kern_return_t kr = bootstrap_look_up( | |
159 bootstrap_port, const_cast<char*>(mach_port_name.c_str()), &port); | |
160 if (kr != KERN_SUCCESS) { | |
161 BOOTSTRAP_LOG(ERROR, kr) << "bootstrap_look_up"; | |
162 return; | |
Robert Sesek
2015/05/15 21:45:05
If this fails, then an instance of this class will
reveman
2015/05/18 18:15:38
I changed how this is initialized in latest patch.
| |
163 } | |
164 send_port_.reset(port); | |
165 } | |
166 | |
167 ChildIOSurfaceManager::~ChildIOSurfaceManager() { | |
168 } | |
169 | |
170 } // namespace content | |
OLD | NEW |