Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: content/browser/browser_io_surface_manager_mac.cc

Issue 1137453002: content: Pass IOSurface references using Mach IPC. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: update comment Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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/browser/browser_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/bind.h"
13 #include "base/logging.h"
14 #include "base/mac/foundation_util.h"
15 #include "base/mac/mach_logging.h"
16 #include "base/strings/stringprintf.h"
17 #include "content/browser/gpu/browser_gpu_channel_host_factory.h"
18 #include "content/browser/renderer_host/render_process_host_impl.h"
19 #include "content/common/mac/io_surface_manager.h"
20 #include "content/common/mac/io_surface_manager_messages.h"
21 #include "content/public/browser/browser_thread.h"
22
23 namespace content {
24
25 // static
26 BrowserIOSurfaceManager* BrowserIOSurfaceManager::GetInstance() {
27 return Singleton<BrowserIOSurfaceManager,
28 LeakySingletonTraits<BrowserIOSurfaceManager>>::get();
29 }
30
31 bool BrowserIOSurfaceManager::RegisterIOSurface(int io_surface_id,
32 int client_id,
33 IOSurfaceRef io_surface) {
34 base::AutoLock lock(lock_);
35
36 IOSurfaceMapKey key(io_surface_id, client_id);
37 DCHECK(io_surfaces_.find(key) == io_surfaces_.end());
Robert Sesek 2015/05/15 21:45:04 This DCHECK will continue in release mode (same bu
reveman 2015/05/18 18:15:38 This is for in-process use only. e.g. the browser
38 io_surfaces_.add(key, make_scoped_ptr(new base::mac::ScopedMachSendRight(
39 IOSurfaceCreateMachPort(io_surface))));
40 return true;
41 }
42
43 void BrowserIOSurfaceManager::UnregisterIOSurface(int io_surface_id,
44 int client_id) {
45 base::AutoLock lock(lock_);
46
47 IOSurfaceMapKey key(io_surface_id, client_id);
48 DCHECK(io_surfaces_.find(key) != io_surfaces_.end());
Robert Sesek 2015/05/15 21:45:04 Same.
reveman 2015/05/18 18:15:38 Same reply.
49 io_surfaces_.erase(key);
50 }
51
52 IOSurfaceRef BrowserIOSurfaceManager::AcquireIOSurface(int io_surface_id) {
53 base::AutoLock lock(lock_);
54
55 IOSurfaceMapKey key(
56 io_surface_id,
57 BrowserGpuChannelHostFactory::instance()->GetGpuChannelId());
58 auto it = io_surfaces_.find(key);
59 if (it == io_surfaces_.end()) {
60 LOG(ERROR) << "Invalid Id for IOSurface " << io_surface_id;
61 return nullptr;
62 }
63
64 return IOSurfaceLookupFromMachPort(it->second->get());
65 }
66
67 gpu::Mailbox BrowserIOSurfaceManager::GenerateChildProcessMailbox(
68 int client_id) {
69 base::AutoLock lock(lock_);
70
71 gpu::Mailbox mailbox = gpu::Mailbox::Generate();
72 DCHECK(mailbox.Verify());
73 child_process_ids_[mailbox] = client_id;
74 return mailbox;
75 }
76
77 void BrowserIOSurfaceManager::InvalidateChildProcessMailbox(
78 const gpu::Mailbox& mailbox) {
79 base::AutoLock lock(lock_);
80
81 DCHECK(child_process_ids_.find(mailbox) != child_process_ids_.end());
82 child_process_ids_.erase(mailbox);
83 }
84
85 gpu::Mailbox BrowserIOSurfaceManager::GetGpuProcessMailbox() const {
86 DCHECK(gpu_process_mailbox_.Verify());
87 return gpu_process_mailbox_;
88 }
89
90 BrowserIOSurfaceManager::BrowserIOSurfaceManager()
91 : gpu_process_mailbox_(gpu::Mailbox::Generate()) {
Robert Sesek 2015/05/15 21:45:04 DCHECK(gpu_process_mailbox_.Verify()) ?
reveman 2015/05/18 18:15:38 Done. Removed the DCHECK in GetGpuProcessMailbox()
92 // Check in with launchd and publish the service name.
93 std::string mach_port_name = base::StringPrintf(
94 "%s.iosurfacemgr.%d", base::mac::BaseBundleID(), getpid());
95 mach_port_t port;
96 kern_return_t kr =
97 bootstrap_check_in(bootstrap_port, mach_port_name.c_str(), &port);
98 if (kr != KERN_SUCCESS) {
99 BOOTSTRAP_LOG(ERROR, kr) << "bootstrap_check_in";
100 return;
101 }
102 server_port_.reset(port);
103
104 // Start the dispatch source.
105 std::string queue_name =
106 base::StringPrintf("%s.IOSurfaceManager", base::mac::BaseBundleID());
107 dispatch_source_.reset(
108 new base::DispatchSourceMach(queue_name.c_str(), server_port_.get(), ^{
109 HandleRequest();
110 }));
111 dispatch_source_->Resume();
112 }
113
114 BrowserIOSurfaceManager::~BrowserIOSurfaceManager() {
115 }
116
117 void BrowserIOSurfaceManager::HandleRequest() {
118 struct {
119 union {
120 mach_msg_header_t header;
121 struct {
122 mach_msg_header_t header;
123 mach_msg_body_t body;
124 IOSurfaceManagerHostMsg_RegisterIOSurface msg;
Robert Sesek 2015/05/15 21:45:04 This entire struct is the message. The struct decl
reveman 2015/05/18 18:15:38 Done by using mailbox_name[64] in the message stru
125 gpu::Mailbox mailbox;
126 } register_io_surface;
Robert Sesek 2015/05/15 21:45:04 These message structs should be in a common file,
reveman 2015/05/18 18:15:38 Done.
reveman 2015/05/18 18:15:38 Done.
127 struct {
128 mach_msg_header_t header;
129 mach_msg_body_t body;
130 IOSurfaceManagerHostMsg_UnregisterIOSurface msg;
131 gpu::Mailbox mailbox;
132 } unregister_io_surface;
133 struct {
134 mach_msg_header_t header;
135 mach_msg_body_t body;
136 IOSurfaceManagerHostMsg_AcquireIOSurface msg;
137 gpu::Mailbox mailbox;
138 } acquire_io_surface;
139 } msg;
140 mach_msg_trailer_t trailer;
141 } data = {{{0}}};
142 data.msg.header.msgh_size = sizeof(data);
143 data.msg.header.msgh_local_port = server_port_.get();
144
145 kern_return_t kr =
146 mach_msg(&data.msg.header, MACH_RCV_MSG, 0, sizeof(data), server_port_,
147 MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
148 if (kr != KERN_SUCCESS) {
149 MACH_LOG(ERROR, kr) << "mach_msg";
150 return;
151 }
152
153 switch (data.msg.header.msgh_id) {
154 case IOSurfaceManagerHostMsg_RegisterIOSurface::ID:
155 OnRegisterIOSurface(data.msg.header,
156 data.msg.register_io_surface.msg.io_surface_id,
157 data.msg.register_io_surface.msg.client_id,
158 data.msg.register_io_surface.msg.io_surface_port.name,
159 data.msg.register_io_surface.mailbox);
160 break;
161 case IOSurfaceManagerHostMsg_UnregisterIOSurface::ID:
162 OnUnregisterIOSurface(data.msg.header,
163 data.msg.unregister_io_surface.msg.io_surface_id,
164 data.msg.unregister_io_surface.msg.client_id,
165 data.msg.unregister_io_surface.mailbox);
166 break;
167 case IOSurfaceManagerHostMsg_AcquireIOSurface::ID:
168 OnAcquireIOSurface(data.msg.header,
169 data.msg.acquire_io_surface.msg.io_surface_id,
170 data.msg.acquire_io_surface.mailbox);
171 break;
172 }
173 }
174
175 void BrowserIOSurfaceManager::OnRegisterIOSurface(
176 const mach_msg_header_t& header,
177 int io_surface_id,
178 int client_id,
179 mach_port_t io_surface_port,
180 const gpu::Mailbox& mailbox) {
181 base::AutoLock lock(lock_);
182
183 if (mailbox != gpu_process_mailbox_) {
184 LOG(ERROR) << "Illegal message from non-GPU process!";
185 return;
186 }
187
188 IOSurfaceMapKey key(io_surface_id, client_id);
189 io_surfaces_.add(
190 key,
191 make_scoped_ptr(new base::mac::ScopedMachSendRight(io_surface_port)));
192
193 struct {
194 mach_msg_header_t header;
195 mach_msg_body_t body;
196 IOSurfaceManagerMsg_RegisterIOSurfaceReply msg;
197 } reply = {{0}};
198 reply.header.msgh_bits = MACH_MSGH_BITS_REMOTE(header.msgh_bits);
199 reply.header.msgh_remote_port = header.msgh_remote_port;
200 reply.header.msgh_size = sizeof(reply);
201 reply.msg.result = true;
202 kern_return_t kr =
203 mach_msg(&reply.header, MACH_SEND_MSG | MACH_SEND_TIMEOUT, sizeof(reply),
204 0, MACH_PORT_NULL, 100 /*milliseconds*/, MACH_PORT_NULL);
205 if (kr != KERN_SUCCESS) {
206 MACH_LOG(ERROR, kr) << "mach_msg";
207 }
208 }
209
210 void BrowserIOSurfaceManager::OnUnregisterIOSurface(
211 const mach_msg_header_t& header,
212 int io_surface_id,
213 int client_id,
214 const gpu::Mailbox& mailbox) {
215 base::AutoLock lock(lock_);
216
217 if (mailbox != gpu_process_mailbox_) {
218 LOG(ERROR) << "Illegal message from non-GPU process!";
219 return;
220 }
221
222 IOSurfaceMapKey key(io_surface_id, client_id);
223 io_surfaces_.erase(key);
224 }
Robert Sesek 2015/05/15 21:45:05 Registration gets a reply but unregistration does
reveman 2015/05/18 18:15:38 Registration needs to be synchronous to prevent th
Robert Sesek 2015/05/19 23:26:23 Makes sense. It's fine to leave this as a one-way
225
226 void BrowserIOSurfaceManager::OnAcquireIOSurface(
227 const mach_msg_header_t& header,
228 int io_surface_id,
229 const gpu::Mailbox& mailbox) {
230 base::AutoLock lock(lock_);
231
232 auto child_process_id_it = child_process_ids_.find(mailbox);
233 if (child_process_id_it == child_process_ids_.end()) {
234 LOG(ERROR) << "Illegal message from non-child process!";
235 return;
236 }
237
238 IOSurfaceMapKey key(io_surface_id, child_process_id_it->second);
239 auto it = io_surfaces_.find(key);
240 if (it == io_surfaces_.end()) {
241 LOG(ERROR) << "Invalid Id for IOSurface " << io_surface_id;
242 return;
243 }
244
245 struct {
246 mach_msg_header_t header;
247 mach_msg_body_t body;
248 IOSurfaceManagerMsg_AcquireIOSurfaceReply msg;
249 } reply = {{0}};
250 reply.header.msgh_bits =
251 MACH_MSGH_BITS_REMOTE(header.msgh_bits) | MACH_MSGH_BITS_COMPLEX;
252 reply.header.msgh_remote_port = header.msgh_remote_port;
253 reply.header.msgh_size = sizeof(reply);
254 reply.body.msgh_descriptor_count = 1;
255 reply.msg.io_surface_port.name = it->second->get();
256 reply.msg.io_surface_port.disposition = MACH_MSG_TYPE_COPY_SEND;
257 reply.msg.io_surface_port.type = MACH_MSG_PORT_DESCRIPTOR;
258 kern_return_t kr =
259 mach_msg(&reply.header, MACH_SEND_MSG | MACH_SEND_TIMEOUT, sizeof(reply),
260 0, MACH_PORT_NULL, 100 /*milliseconds*/, MACH_PORT_NULL);
261 if (kr != KERN_SUCCESS) {
262 MACH_LOG(ERROR, kr) << "mach_msg";
263 }
264 }
265
266 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698