OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ppapi/proxy/ppb_image_data_proxy.h" | 5 #include "ppapi/proxy/ppb_image_data_proxy.h" |
6 | 6 |
7 #include <string.h> // For memcpy | 7 #include <string.h> // For memcpy |
8 | 8 |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "build/build_config.h" | 12 #include "build/build_config.h" |
13 #include "ppapi/c/pp_completion_callback.h" | 13 #include "ppapi/c/pp_completion_callback.h" |
14 #include "ppapi/c/pp_errors.h" | 14 #include "ppapi/c/pp_errors.h" |
15 #include "ppapi/c/pp_resource.h" | 15 #include "ppapi/c/pp_resource.h" |
16 #include "ppapi/proxy/host_dispatcher.h" | |
16 #include "ppapi/proxy/plugin_dispatcher.h" | 17 #include "ppapi/proxy/plugin_dispatcher.h" |
17 #include "ppapi/proxy/plugin_resource_tracker.h" | 18 #include "ppapi/proxy/plugin_resource_tracker.h" |
18 #include "ppapi/proxy/ppapi_messages.h" | 19 #include "ppapi/proxy/ppapi_messages.h" |
19 #include "ppapi/shared_impl/host_resource.h" | 20 #include "ppapi/shared_impl/host_resource.h" |
20 #include "ppapi/shared_impl/resource.h" | 21 #include "ppapi/shared_impl/resource.h" |
21 #include "ppapi/thunk/enter.h" | 22 #include "ppapi/thunk/enter.h" |
22 #include "ppapi/thunk/thunk.h" | 23 #include "ppapi/thunk/thunk.h" |
23 | 24 |
24 #if !defined(OS_NACL) | 25 #if !defined(OS_NACL) |
25 #include "skia/ext/platform_canvas.h" | 26 #include "skia/ext/platform_canvas.h" |
26 #include "ui/surface/transport_dib.h" | 27 #include "ui/surface/transport_dib.h" |
27 #endif | 28 #endif |
28 | 29 |
29 namespace ppapi { | 30 namespace ppapi { |
30 namespace proxy { | 31 namespace proxy { |
31 | 32 |
33 #if !defined(OS_NACL) | |
32 ImageData::ImageData(const HostResource& resource, | 34 ImageData::ImageData(const HostResource& resource, |
33 const PP_ImageDataDesc& desc, | 35 const PP_ImageDataDesc& desc, |
34 ImageHandle handle) | 36 ImageHandle handle) |
35 : Resource(OBJECT_IS_PROXY, resource), | 37 : Resource(OBJECT_IS_PROXY, resource), |
36 desc_(desc) { | 38 desc_(desc) { |
37 #if defined(OS_NACL) | 39 #if defined(OS_WIN) |
38 // TODO(brettw) implement NaCl ImageData. This will involve just | |
39 // memory-mapping the handle as raw memory rather than as a transport DIB. | |
40 NOTIMPLEMENTED(); | |
41 #elif defined(OS_WIN) | |
42 transport_dib_.reset(TransportDIB::CreateWithHandle(handle)); | 40 transport_dib_.reset(TransportDIB::CreateWithHandle(handle)); |
43 #else | 41 #else |
44 transport_dib_.reset(TransportDIB::Map(handle)); | 42 transport_dib_.reset(TransportDIB::Map(handle)); |
45 #endif | 43 #endif // defined(OS_WIN) |
46 } | 44 } |
45 #else // !defined(OS_NACL) | |
46 | |
47 ImageData::ImageData(const HostResource& resource, | |
48 const PP_ImageDataDesc& desc, | |
49 const base::SharedMemoryHandle& handle) | |
50 : Resource(OBJECT_IS_PROXY, resource), | |
51 desc_(desc), | |
52 shm_(handle, false /* read_only */), | |
53 size_(desc.size.width * desc.size.height * 4), | |
54 map_count_(0) { | |
55 } | |
56 #endif // !defined(OS_NACL) | |
47 | 57 |
48 ImageData::~ImageData() { | 58 ImageData::~ImageData() { |
49 } | 59 } |
50 | 60 |
51 thunk::PPB_ImageData_API* ImageData::AsPPB_ImageData_API() { | 61 thunk::PPB_ImageData_API* ImageData::AsPPB_ImageData_API() { |
52 return this; | 62 return this; |
53 } | 63 } |
54 | 64 |
55 PP_Bool ImageData::Describe(PP_ImageDataDesc* desc) { | 65 PP_Bool ImageData::Describe(PP_ImageDataDesc* desc) { |
56 memcpy(desc, &desc_, sizeof(PP_ImageDataDesc)); | 66 memcpy(desc, &desc_, sizeof(PP_ImageDataDesc)); |
57 return PP_TRUE; | 67 return PP_TRUE; |
58 } | 68 } |
59 | 69 |
60 void* ImageData::Map() { | 70 void* ImageData::Map() { |
61 #if defined(OS_NACL) | 71 #if defined(OS_NACL) |
62 NOTIMPLEMENTED(); | 72 if (map_count_++ == 0) |
73 shm_.Map(size_); | |
74 return shm_.memory(); | |
63 #else | 75 #else |
64 if (!mapped_canvas_.get()) { | 76 if (!mapped_canvas_.get()) { |
65 mapped_canvas_.reset(transport_dib_->GetPlatformCanvas(desc_.size.width, | 77 mapped_canvas_.reset(transport_dib_->GetPlatformCanvas(desc_.size.width, |
66 desc_.size.height)); | 78 desc_.size.height)); |
67 if (!mapped_canvas_.get()) | 79 if (!mapped_canvas_.get()) |
68 return NULL; | 80 return NULL; |
69 } | 81 } |
70 const SkBitmap& bitmap = | 82 const SkBitmap& bitmap = |
71 skia::GetTopDevice(*mapped_canvas_)->accessBitmap(true); | 83 skia::GetTopDevice(*mapped_canvas_)->accessBitmap(true); |
72 | 84 |
73 bitmap.lockPixels(); | 85 bitmap.lockPixels(); |
74 return bitmap.getAddr(0, 0); | 86 return bitmap.getAddr(0, 0); |
75 #endif | 87 #endif |
76 } | 88 } |
77 | 89 |
78 void ImageData::Unmap() { | 90 void ImageData::Unmap() { |
79 #if defined(OS_NACL) | 91 #if defined(OS_NACL) |
80 NOTIMPLEMENTED(); | 92 if (--map_count_ == 0) |
93 shm_.Unmap(); | |
81 #else | 94 #else |
82 // TODO(brettw) have a way to unmap a TransportDIB. Currently this isn't | 95 // TODO(brettw) have a way to unmap a TransportDIB. Currently this isn't |
83 // possible since deleting the TransportDIB also frees all the handles. | 96 // possible since deleting the TransportDIB also frees all the handles. |
84 // We need to add a method to TransportDIB to release the handles. | 97 // We need to add a method to TransportDIB to release the handles. |
85 #endif | 98 #endif |
86 } | 99 } |
87 | 100 |
88 int32_t ImageData::GetSharedMemory(int* /* handle */, | 101 int32_t ImageData::GetSharedMemory(int* /* handle */, |
89 uint32_t* /* byte_count */) { | 102 uint32_t* /* byte_count */) { |
90 // Not supported in the proxy (this method is for actually implementing the | 103 // Not supported in the proxy (this method is for actually implementing the |
91 // proxy in the host). | 104 // proxy in the host). |
92 return PP_ERROR_NOACCESS; | 105 return PP_ERROR_NOACCESS; |
93 } | 106 } |
94 | 107 |
95 skia::PlatformCanvas* ImageData::GetPlatformCanvas() { | 108 skia::PlatformCanvas* ImageData::GetPlatformCanvas() { |
96 #if defined(OS_NACL) | 109 #if defined(OS_NACL) |
97 return NULL; // No canvas in NaCl. | 110 return NULL; // No canvas in NaCl. |
98 #else | 111 #else |
99 return mapped_canvas_.get(); | 112 return mapped_canvas_.get(); |
100 #endif | 113 #endif |
101 } | 114 } |
102 | 115 |
116 SkCanvas* ImageData::GetCanvas() { | |
117 #if defined(OS_NACL) | |
118 return NULL; // No canvas in NaCl. | |
119 #else | |
120 return mapped_canvas_.get(); | |
121 #endif | |
122 } | |
123 | |
124 #if !defined(OS_NACL) | |
103 // static | 125 // static |
104 ImageHandle ImageData::NullHandle() { | 126 ImageHandle ImageData::NullHandle() { |
105 #if defined(OS_WIN) | 127 #if defined(OS_WIN) |
106 return NULL; | 128 return NULL; |
107 #elif defined(OS_MACOSX) || defined(OS_ANDROID) | 129 #elif defined(OS_MACOSX) || defined(OS_ANDROID) |
108 return ImageHandle(); | 130 return ImageHandle(); |
109 #else | 131 #else |
110 return 0; | 132 return 0; |
111 #endif | 133 #endif |
112 } | 134 } |
113 | 135 |
114 ImageHandle ImageData::HandleFromInt(int32_t i) { | 136 ImageHandle ImageData::HandleFromInt(int32_t i) { |
115 #if defined(OS_WIN) | 137 #if defined(OS_WIN) |
116 return reinterpret_cast<ImageHandle>(i); | 138 return reinterpret_cast<ImageHandle>(i); |
117 #elif defined(OS_MACOSX) || defined(OS_ANDROID) | 139 #elif defined(OS_MACOSX) || defined(OS_ANDROID) |
118 return ImageHandle(i, false); | 140 return ImageHandle(i, false); |
119 #else | 141 #else |
120 return static_cast<ImageHandle>(i); | 142 return static_cast<ImageHandle>(i); |
121 #endif | 143 #endif |
122 } | 144 } |
145 #endif // !defined(OS_NACL) | |
123 | 146 |
124 PPB_ImageData_Proxy::PPB_ImageData_Proxy(Dispatcher* dispatcher) | 147 PPB_ImageData_Proxy::PPB_ImageData_Proxy(Dispatcher* dispatcher) |
125 : InterfaceProxy(dispatcher) { | 148 : InterfaceProxy(dispatcher) { |
126 } | 149 } |
127 | 150 |
128 PPB_ImageData_Proxy::~PPB_ImageData_Proxy() { | 151 PPB_ImageData_Proxy::~PPB_ImageData_Proxy() { |
129 } | 152 } |
130 | 153 |
131 // static | 154 // static |
132 PP_Resource PPB_ImageData_Proxy::CreateProxyResource(PP_Instance instance, | 155 PP_Resource PPB_ImageData_Proxy::CreateProxyResource(PP_Instance instance, |
133 PP_ImageDataFormat format, | 156 PP_ImageDataFormat format, |
134 const PP_Size& size, | 157 const PP_Size& size, |
135 PP_Bool init_to_zero) { | 158 PP_Bool init_to_zero) { |
136 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); | 159 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); |
137 if (!dispatcher) | 160 if (!dispatcher) |
138 return 0; | 161 return 0; |
139 | 162 |
140 HostResource result; | 163 HostResource result; |
141 std::string image_data_desc; | 164 std::string image_data_desc; |
165 #if defined(OS_NACL) | |
166 base::SharedMemoryHandle image_handle = base::SharedMemory::NULLHandle(); | |
167 dispatcher->Send(new PpapiHostMsg_PPBImageData_CreateNaCl( | |
168 kApiID, instance, format, size, init_to_zero, | |
169 &result, &image_data_desc, &image_handle)); | |
170 #else | |
142 ImageHandle image_handle = ImageData::NullHandle(); | 171 ImageHandle image_handle = ImageData::NullHandle(); |
143 dispatcher->Send(new PpapiHostMsg_PPBImageData_Create( | 172 dispatcher->Send(new PpapiHostMsg_PPBImageData_Create( |
144 kApiID, instance, format, size, init_to_zero, | 173 kApiID, instance, format, size, init_to_zero, |
145 &result, &image_data_desc, &image_handle)); | 174 &result, &image_data_desc, &image_handle)); |
175 #endif | |
146 | 176 |
147 if (result.is_null() || image_data_desc.size() != sizeof(PP_ImageDataDesc)) | 177 if (result.is_null() || image_data_desc.size() != sizeof(PP_ImageDataDesc)) |
148 return 0; | 178 return 0; |
149 | 179 |
150 // We serialize the PP_ImageDataDesc just by copying to a string. | 180 // We serialize the PP_ImageDataDesc just by copying to a string. |
151 PP_ImageDataDesc desc; | 181 PP_ImageDataDesc desc; |
152 memcpy(&desc, image_data_desc.data(), sizeof(PP_ImageDataDesc)); | 182 memcpy(&desc, image_data_desc.data(), sizeof(PP_ImageDataDesc)); |
153 | 183 |
154 return (new ImageData(result, desc, image_handle))->GetReference(); | 184 return (new ImageData(result, desc, image_handle))->GetReference(); |
155 } | 185 } |
156 | 186 |
157 bool PPB_ImageData_Proxy::OnMessageReceived(const IPC::Message& msg) { | 187 bool PPB_ImageData_Proxy::OnMessageReceived(const IPC::Message& msg) { |
158 bool handled = true; | 188 bool handled = true; |
159 IPC_BEGIN_MESSAGE_MAP(PPB_ImageData_Proxy, msg) | 189 IPC_BEGIN_MESSAGE_MAP(PPB_ImageData_Proxy, msg) |
160 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBImageData_Create, OnHostMsgCreate) | 190 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBImageData_Create, OnHostMsgCreate) |
191 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBImageData_CreateNaCl, | |
192 OnHostMsgCreateNaCl) | |
161 IPC_MESSAGE_UNHANDLED(handled = false) | 193 IPC_MESSAGE_UNHANDLED(handled = false) |
162 IPC_END_MESSAGE_MAP() | 194 IPC_END_MESSAGE_MAP() |
163 return handled; | 195 return handled; |
164 } | 196 } |
165 | 197 |
166 void PPB_ImageData_Proxy::OnHostMsgCreate(PP_Instance instance, | 198 void PPB_ImageData_Proxy::OnHostMsgCreate(PP_Instance instance, |
167 int32_t format, | 199 int32_t format, |
168 const PP_Size& size, | 200 const PP_Size& size, |
169 PP_Bool init_to_zero, | 201 PP_Bool init_to_zero, |
170 HostResource* result, | 202 HostResource* result, |
171 std::string* image_data_desc, | 203 std::string* image_data_desc, |
172 ImageHandle* result_image_handle) { | 204 ImageHandle* result_image_handle) { |
205 #if defined(OS_NACL) | |
206 return; | |
207 #else | |
173 *result_image_handle = ImageData::NullHandle(); | 208 *result_image_handle = ImageData::NullHandle(); |
174 | 209 |
175 thunk::EnterResourceCreation enter(instance); | 210 thunk::EnterResourceCreation enter(instance); |
176 if (enter.failed()) | 211 if (enter.failed()) |
177 return; | 212 return; |
178 | 213 |
179 PP_Resource resource = enter.functions()->CreateImageData( | 214 PP_Resource resource = enter.functions()->CreateImageData( |
180 instance, static_cast<PP_ImageDataFormat>(format), size, init_to_zero); | 215 instance, static_cast<PP_ImageDataFormat>(format), size, init_to_zero); |
181 if (!resource) | 216 if (!resource) |
182 return; | 217 return; |
(...skipping 10 matching lines...) Expand all Loading... | |
193 | 228 |
194 // Get the shared memory handle. | 229 // Get the shared memory handle. |
195 uint32_t byte_count = 0; | 230 uint32_t byte_count = 0; |
196 int32_t handle = 0; | 231 int32_t handle = 0; |
197 if (enter_resource.object()->GetSharedMemory(&handle, &byte_count) == PP_OK) { | 232 if (enter_resource.object()->GetSharedMemory(&handle, &byte_count) == PP_OK) { |
198 #if defined(OS_WIN) | 233 #if defined(OS_WIN) |
199 ImageHandle ih = ImageData::HandleFromInt(handle); | 234 ImageHandle ih = ImageData::HandleFromInt(handle); |
200 *result_image_handle = dispatcher()->ShareHandleWithRemote(ih, false); | 235 *result_image_handle = dispatcher()->ShareHandleWithRemote(ih, false); |
201 #else | 236 #else |
202 *result_image_handle = ImageData::HandleFromInt(handle); | 237 *result_image_handle = ImageData::HandleFromInt(handle); |
203 #endif | 238 #endif // defined(OS_WIN) |
204 } | 239 } |
240 #endif // defined(OS_NACL) | |
241 } | |
242 | |
243 void PPB_ImageData_Proxy::OnHostMsgCreateNaCl( | |
244 PP_Instance instance, | |
245 int32_t format, | |
246 const PP_Size& size, | |
247 PP_Bool init_to_zero, | |
248 HostResource* result, | |
249 std::string* image_data_desc, | |
250 base::SharedMemoryHandle* result_image_handle) { | |
251 #if defined(OS_NACL) | |
brettw
2012/07/20 22:02:28
This seems weird, does this code do anything?
dmichael (off chromium)
2012/07/20 22:32:40
It does, but only in the trusted side. The message
| |
252 return; | |
253 #else | |
254 *result_image_handle = base::SharedMemory::NULLHandle(); | |
255 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); | |
256 if (!dispatcher) | |
257 return; | |
258 | |
259 thunk::EnterResourceCreation enter(instance); | |
260 if (enter.failed()) | |
261 return; | |
262 | |
263 PP_Resource resource = enter.functions()->CreateImageDataNaCl( | |
264 instance, static_cast<PP_ImageDataFormat>(format), size, init_to_zero); | |
265 if (!resource) | |
266 return; | |
267 result->SetHostResource(instance, resource); | |
268 | |
269 // Get the description, it's just serialized as a string. | |
270 thunk::EnterResourceNoLock<thunk::PPB_ImageData_API> enter_resource( | |
271 resource, false); | |
272 if (enter_resource.failed()) | |
273 return; | |
274 PP_ImageDataDesc desc; | |
275 if (enter_resource.object()->Describe(&desc) == PP_TRUE) { | |
276 image_data_desc->resize(sizeof(PP_ImageDataDesc)); | |
277 memcpy(&(*image_data_desc)[0], &desc, sizeof(PP_ImageDataDesc)); | |
278 } | |
279 int local_fd; | |
280 uint32_t byte_count; | |
281 if (enter_resource.object()->GetSharedMemory(&local_fd, &byte_count) != PP_OK) | |
282 return; | |
283 | |
284 // TODO(dmichael): Change trusted interface to return a PP_FileHandle, those | |
285 // casts are ugly. | |
286 base::PlatformFile platform_file = | |
287 #if defined(OS_WIN) | |
288 reinterpret_cast<HANDLE>(static_cast<intptr_t>(local_fd)); | |
289 #elif defined(OS_POSIX) | |
290 local_fd; | |
291 #else | |
292 #error Not implemented. | |
293 #endif // defined(OS_WIN) | |
294 *result_image_handle = | |
295 dispatcher->ShareHandleWithRemote(platform_file, false); | |
296 #endif // defined(OS_NACL) | |
205 } | 297 } |
206 | 298 |
207 } // namespace proxy | 299 } // namespace proxy |
208 } // namespace ppapi | 300 } // namespace ppapi |
OLD | NEW |