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/host_dispatcher.h" |
17 #include "ppapi/proxy/plugin_dispatcher.h" | 17 #include "ppapi/proxy/plugin_dispatcher.h" |
18 #include "ppapi/proxy/plugin_resource_tracker.h" | 18 #include "ppapi/proxy/plugin_resource_tracker.h" |
19 #include "ppapi/proxy/ppapi_messages.h" | 19 #include "ppapi/proxy/ppapi_messages.h" |
20 #include "ppapi/shared_impl/host_resource.h" | 20 #include "ppapi/shared_impl/host_resource.h" |
21 #include "ppapi/shared_impl/resource.h" | 21 #include "ppapi/shared_impl/resource.h" |
22 #include "ppapi/thunk/enter.h" | 22 #include "ppapi/thunk/enter.h" |
23 #include "ppapi/thunk/thunk.h" | 23 #include "ppapi/thunk/thunk.h" |
24 | 24 |
25 #if !defined(OS_NACL) | 25 #if !defined(OS_NACL) && !defined(NACL_WIN64) |
26 #include "skia/ext/platform_canvas.h" | 26 #include "skia/ext/platform_canvas.h" |
27 #include "ui/surface/transport_dib.h" | 27 #include "ui/surface/transport_dib.h" |
28 #endif | 28 #endif |
29 | 29 |
30 namespace ppapi { | 30 namespace ppapi { |
31 namespace proxy { | 31 namespace proxy { |
32 | 32 |
33 #if !defined(OS_NACL) | 33 #if !defined(OS_NACL) && !defined(NACL_WIN64) |
34 ImageData::ImageData(const HostResource& resource, | 34 ImageData::ImageData(const HostResource& resource, |
35 const PP_ImageDataDesc& desc, | 35 const PP_ImageDataDesc& desc, |
36 ImageHandle handle) | 36 ImageHandle handle) |
37 : Resource(OBJECT_IS_PROXY, resource), | 37 : Resource(OBJECT_IS_PROXY, resource), |
38 desc_(desc) { | 38 desc_(desc) { |
39 #if defined(OS_WIN) | 39 #if defined(OS_WIN) |
40 transport_dib_.reset(TransportDIB::CreateWithHandle(handle)); | 40 transport_dib_.reset(TransportDIB::CreateWithHandle(handle)); |
41 #else | 41 #else |
42 transport_dib_.reset(TransportDIB::Map(handle)); | 42 transport_dib_.reset(TransportDIB::Map(handle)); |
43 #endif // defined(OS_WIN) | 43 #endif // defined(OS_WIN) |
44 } | 44 } |
45 #else // !defined(OS_NACL) | 45 #else // !defined(OS_NACL) && !defined(NACL_WIN64) |
46 | 46 |
47 ImageData::ImageData(const HostResource& resource, | 47 ImageData::ImageData(const HostResource& resource, |
48 const PP_ImageDataDesc& desc, | 48 const PP_ImageDataDesc& desc, |
49 const base::SharedMemoryHandle& handle) | 49 const base::SharedMemoryHandle& handle) |
50 : Resource(OBJECT_IS_PROXY, resource), | 50 : Resource(OBJECT_IS_PROXY, resource), |
51 desc_(desc), | 51 desc_(desc), |
52 shm_(handle, false /* read_only */), | 52 shm_(handle, false /* read_only */), |
53 size_(desc.size.width * desc.size.height * 4), | 53 size_(desc.size.width * desc.size.height * 4), |
54 map_count_(0) { | 54 map_count_(0) { |
55 } | 55 } |
56 #endif // !defined(OS_NACL) | 56 #endif // else, !defined(OS_NACL) && !defined(NACL_WIN64) |
57 | 57 |
58 ImageData::~ImageData() { | 58 ImageData::~ImageData() { |
59 } | 59 } |
60 | 60 |
61 thunk::PPB_ImageData_API* ImageData::AsPPB_ImageData_API() { | 61 thunk::PPB_ImageData_API* ImageData::AsPPB_ImageData_API() { |
62 return this; | 62 return this; |
63 } | 63 } |
64 | 64 |
65 PP_Bool ImageData::Describe(PP_ImageDataDesc* desc) { | 65 PP_Bool ImageData::Describe(PP_ImageDataDesc* desc) { |
66 memcpy(desc, &desc_, sizeof(PP_ImageDataDesc)); | 66 memcpy(desc, &desc_, sizeof(PP_ImageDataDesc)); |
67 return PP_TRUE; | 67 return PP_TRUE; |
68 } | 68 } |
69 | 69 |
70 void* ImageData::Map() { | 70 void* ImageData::Map() { |
71 #if defined(OS_NACL) | 71 #if defined(OS_NACL) || defined(NACL_WIN64) |
72 if (map_count_++ == 0) | 72 if (map_count_++ == 0) |
73 shm_.Map(size_); | 73 shm_.Map(size_); |
74 return shm_.memory(); | 74 return shm_.memory(); |
75 #else | 75 #else |
76 if (!mapped_canvas_.get()) { | 76 if (!mapped_canvas_.get()) { |
77 mapped_canvas_.reset(transport_dib_->GetPlatformCanvas(desc_.size.width, | 77 mapped_canvas_.reset(transport_dib_->GetPlatformCanvas(desc_.size.width, |
78 desc_.size.height)); | 78 desc_.size.height)); |
79 if (!mapped_canvas_.get()) | 79 if (!mapped_canvas_.get()) |
80 return NULL; | 80 return NULL; |
81 } | 81 } |
82 const SkBitmap& bitmap = | 82 const SkBitmap& bitmap = |
83 skia::GetTopDevice(*mapped_canvas_)->accessBitmap(true); | 83 skia::GetTopDevice(*mapped_canvas_)->accessBitmap(true); |
84 | 84 |
85 bitmap.lockPixels(); | 85 bitmap.lockPixels(); |
86 return bitmap.getAddr(0, 0); | 86 return bitmap.getAddr(0, 0); |
87 #endif | 87 #endif |
88 } | 88 } |
89 | 89 |
90 void ImageData::Unmap() { | 90 void ImageData::Unmap() { |
91 #if defined(OS_NACL) | 91 #if defined(OS_NACL) || defined(NACL_WIN64) |
92 if (--map_count_ == 0) | 92 if (--map_count_ == 0) |
93 shm_.Unmap(); | 93 shm_.Unmap(); |
94 #else | 94 #else |
95 // 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 |
96 // possible since deleting the TransportDIB also frees all the handles. | 96 // possible since deleting the TransportDIB also frees all the handles. |
97 // 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. |
98 #endif | 98 #endif |
99 } | 99 } |
100 | 100 |
101 int32_t ImageData::GetSharedMemory(int* /* handle */, | 101 int32_t ImageData::GetSharedMemory(int* /* handle */, |
102 uint32_t* /* byte_count */) { | 102 uint32_t* /* byte_count */) { |
103 // 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 |
104 // proxy in the host). | 104 // proxy in the host). |
105 return PP_ERROR_NOACCESS; | 105 return PP_ERROR_NOACCESS; |
106 } | 106 } |
107 | 107 |
108 skia::PlatformCanvas* ImageData::GetPlatformCanvas() { | 108 skia::PlatformCanvas* ImageData::GetPlatformCanvas() { |
109 #if defined(OS_NACL) | 109 #if defined(OS_NACL) || defined(NACL_WIN64) |
110 return NULL; // No canvas in NaCl. | 110 return NULL; // No canvas in NaCl. |
111 #else | 111 #else |
112 return mapped_canvas_.get(); | 112 return mapped_canvas_.get(); |
113 #endif | 113 #endif |
114 } | 114 } |
115 | 115 |
116 SkCanvas* ImageData::GetCanvas() { | 116 SkCanvas* ImageData::GetCanvas() { |
117 #if defined(OS_NACL) | 117 #if defined(OS_NACL) || defined(NACL_WIN64) |
118 return NULL; // No canvas in NaCl. | 118 return NULL; // No canvas in NaCl. |
119 #else | 119 #else |
120 return mapped_canvas_.get(); | 120 return mapped_canvas_.get(); |
121 #endif | 121 #endif |
122 } | 122 } |
123 | 123 |
124 #if !defined(OS_NACL) | 124 #if !defined(OS_NACL) && !defined(NACL_WIN64) |
125 // static | 125 // static |
126 ImageHandle ImageData::NullHandle() { | 126 ImageHandle ImageData::NullHandle() { |
127 #if defined(OS_WIN) | 127 #if defined(OS_WIN) |
128 return NULL; | 128 return NULL; |
129 #elif defined(OS_MACOSX) || defined(OS_ANDROID) | 129 #elif defined(OS_MACOSX) || defined(OS_ANDROID) |
130 return ImageHandle(); | 130 return ImageHandle(); |
131 #else | 131 #else |
132 return 0; | 132 return 0; |
133 #endif | 133 #endif |
134 } | 134 } |
135 | 135 |
136 ImageHandle ImageData::HandleFromInt(int32_t i) { | 136 ImageHandle ImageData::HandleFromInt(int32_t i) { |
137 #if defined(OS_WIN) | 137 #if defined(OS_WIN) |
138 return reinterpret_cast<ImageHandle>(i); | 138 return reinterpret_cast<ImageHandle>(i); |
139 #elif defined(OS_MACOSX) || defined(OS_ANDROID) | 139 #elif defined(OS_MACOSX) || defined(OS_ANDROID) |
140 return ImageHandle(i, false); | 140 return ImageHandle(i, false); |
141 #else | 141 #else |
142 return static_cast<ImageHandle>(i); | 142 return static_cast<ImageHandle>(i); |
143 #endif | 143 #endif |
144 } | 144 } |
145 #endif // !defined(OS_NACL) | 145 #endif // !defined(OS_NACL) || !defined(NACL_WIN64) |
146 | 146 |
147 PPB_ImageData_Proxy::PPB_ImageData_Proxy(Dispatcher* dispatcher) | 147 PPB_ImageData_Proxy::PPB_ImageData_Proxy(Dispatcher* dispatcher) |
148 : InterfaceProxy(dispatcher) { | 148 : InterfaceProxy(dispatcher) { |
149 } | 149 } |
150 | 150 |
151 PPB_ImageData_Proxy::~PPB_ImageData_Proxy() { | 151 PPB_ImageData_Proxy::~PPB_ImageData_Proxy() { |
152 } | 152 } |
153 | 153 |
154 // static | 154 // static |
155 PP_Resource PPB_ImageData_Proxy::CreateProxyResource(PP_Instance instance, | 155 PP_Resource PPB_ImageData_Proxy::CreateProxyResource(PP_Instance instance, |
156 PP_ImageDataFormat format, | 156 PP_ImageDataFormat format, |
157 const PP_Size& size, | 157 const PP_Size& size, |
158 PP_Bool init_to_zero) { | 158 PP_Bool init_to_zero) { |
159 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); | 159 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); |
160 if (!dispatcher) | 160 if (!dispatcher) |
161 return 0; | 161 return 0; |
162 | 162 |
163 HostResource result; | 163 HostResource result; |
164 std::string image_data_desc; | 164 std::string image_data_desc; |
165 #if defined(OS_NACL) | 165 #if defined(OS_NACL) || defined(NACL_WIN64) |
166 base::SharedMemoryHandle image_handle = base::SharedMemory::NULLHandle(); | 166 ppapi::proxy::SerializedHandle image_handle_wrapper; |
167 dispatcher->Send(new PpapiHostMsg_PPBImageData_CreateNaCl( | 167 dispatcher->Send(new PpapiHostMsg_PPBImageData_CreateNaCl( |
168 kApiID, instance, format, size, init_to_zero, | 168 kApiID, instance, format, size, init_to_zero, |
169 &result, &image_data_desc, &image_handle)); | 169 &result, &image_data_desc, &image_handle_wrapper)); |
| 170 if (!image_handle_wrapper.is_shmem()) |
| 171 return 0; |
| 172 base::SharedMemoryHandle image_handle = image_handle_wrapper.shmem(); |
170 #else | 173 #else |
171 ImageHandle image_handle = ImageData::NullHandle(); | 174 ImageHandle image_handle = ImageData::NullHandle(); |
172 dispatcher->Send(new PpapiHostMsg_PPBImageData_Create( | 175 dispatcher->Send(new PpapiHostMsg_PPBImageData_Create( |
173 kApiID, instance, format, size, init_to_zero, | 176 kApiID, instance, format, size, init_to_zero, |
174 &result, &image_data_desc, &image_handle)); | 177 &result, &image_data_desc, &image_handle)); |
175 #endif | 178 #endif |
176 | 179 |
177 if (result.is_null() || image_data_desc.size() != sizeof(PP_ImageDataDesc)) | 180 if (result.is_null() || image_data_desc.size() != sizeof(PP_ImageDataDesc)) |
178 return 0; | 181 return 0; |
179 | 182 |
(...skipping 15 matching lines...) Expand all Loading... |
195 return handled; | 198 return handled; |
196 } | 199 } |
197 | 200 |
198 void PPB_ImageData_Proxy::OnHostMsgCreate(PP_Instance instance, | 201 void PPB_ImageData_Proxy::OnHostMsgCreate(PP_Instance instance, |
199 int32_t format, | 202 int32_t format, |
200 const PP_Size& size, | 203 const PP_Size& size, |
201 PP_Bool init_to_zero, | 204 PP_Bool init_to_zero, |
202 HostResource* result, | 205 HostResource* result, |
203 std::string* image_data_desc, | 206 std::string* image_data_desc, |
204 ImageHandle* result_image_handle) { | 207 ImageHandle* result_image_handle) { |
205 #if defined(OS_NACL) | 208 #if defined(OS_NACL) || defined(NACL_WIN64) |
206 // This message should never be received in untrusted code. To minimize the | 209 // This message should never be received in untrusted code. To minimize the |
207 // size of the IRT, we just don't handle it. | 210 // size of the IRT, we just don't handle it. |
208 return; | 211 return; |
209 #else | 212 #else |
210 *result_image_handle = ImageData::NullHandle(); | 213 *result_image_handle = ImageData::NullHandle(); |
211 | 214 |
212 thunk::EnterResourceCreation enter(instance); | 215 thunk::EnterResourceCreation enter(instance); |
213 if (enter.failed()) | 216 if (enter.failed()) |
214 return; | 217 return; |
215 | 218 |
(...skipping 16 matching lines...) Expand all Loading... |
232 uint32_t byte_count = 0; | 235 uint32_t byte_count = 0; |
233 int32_t handle = 0; | 236 int32_t handle = 0; |
234 if (enter_resource.object()->GetSharedMemory(&handle, &byte_count) == PP_OK) { | 237 if (enter_resource.object()->GetSharedMemory(&handle, &byte_count) == PP_OK) { |
235 #if defined(OS_WIN) | 238 #if defined(OS_WIN) |
236 ImageHandle ih = ImageData::HandleFromInt(handle); | 239 ImageHandle ih = ImageData::HandleFromInt(handle); |
237 *result_image_handle = dispatcher()->ShareHandleWithRemote(ih, false); | 240 *result_image_handle = dispatcher()->ShareHandleWithRemote(ih, false); |
238 #else | 241 #else |
239 *result_image_handle = ImageData::HandleFromInt(handle); | 242 *result_image_handle = ImageData::HandleFromInt(handle); |
240 #endif // defined(OS_WIN) | 243 #endif // defined(OS_WIN) |
241 } | 244 } |
242 #endif // defined(OS_NACL) | 245 #endif // defined(OS_NACL) || defined(NACL_WIN64) |
243 } | 246 } |
244 | 247 |
245 void PPB_ImageData_Proxy::OnHostMsgCreateNaCl( | 248 void PPB_ImageData_Proxy::OnHostMsgCreateNaCl( |
246 PP_Instance instance, | 249 PP_Instance instance, |
247 int32_t format, | 250 int32_t format, |
248 const PP_Size& size, | 251 const PP_Size& size, |
249 PP_Bool init_to_zero, | 252 PP_Bool init_to_zero, |
250 HostResource* result, | 253 HostResource* result, |
251 std::string* image_data_desc, | 254 std::string* image_data_desc, |
252 base::SharedMemoryHandle* result_image_handle) { | 255 ppapi::proxy::SerializedHandle* result_image_handle) { |
253 #if defined(OS_NACL) | 256 #if defined(OS_NACL) || defined(NACL_WIN64) |
254 // This message should never be received in untrusted code. To minimize the | 257 // This message should never be received in untrusted code. To minimize the |
255 // size of the IRT, we just don't handle it. | 258 // size of the IRT, we just don't handle it. |
256 return; | 259 return; |
257 #else | 260 #else |
258 *result_image_handle = base::SharedMemory::NULLHandle(); | 261 result_image_handle->set_null_shmem(); |
259 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); | 262 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); |
260 if (!dispatcher) | 263 if (!dispatcher) |
261 return; | 264 return; |
262 | 265 |
263 thunk::EnterResourceCreation enter(instance); | 266 thunk::EnterResourceCreation enter(instance); |
264 if (enter.failed()) | 267 if (enter.failed()) |
265 return; | 268 return; |
266 | 269 |
267 PP_Resource resource = enter.functions()->CreateImageDataNaCl( | 270 PP_Resource resource = enter.functions()->CreateImageDataNaCl( |
268 instance, static_cast<PP_ImageDataFormat>(format), size, init_to_zero); | 271 instance, static_cast<PP_ImageDataFormat>(format), size, init_to_zero); |
269 if (!resource) | 272 if (!resource) |
270 return; | 273 return; |
271 result->SetHostResource(instance, resource); | 274 result->SetHostResource(instance, resource); |
272 | 275 |
273 // Get the description, it's just serialized as a string. | 276 // Get the description, it's just serialized as a string. |
274 thunk::EnterResourceNoLock<thunk::PPB_ImageData_API> enter_resource( | 277 thunk::EnterResourceNoLock<thunk::PPB_ImageData_API> enter_resource( |
275 resource, false); | 278 resource, false); |
276 if (enter_resource.failed()) | 279 if (enter_resource.failed()) |
277 return; | 280 return; |
278 PP_ImageDataDesc desc; | 281 PP_ImageDataDesc desc; |
279 if (enter_resource.object()->Describe(&desc) == PP_TRUE) { | 282 if (enter_resource.object()->Describe(&desc) == PP_TRUE) { |
280 image_data_desc->resize(sizeof(PP_ImageDataDesc)); | 283 image_data_desc->resize(sizeof(PP_ImageDataDesc)); |
281 memcpy(&(*image_data_desc)[0], &desc, sizeof(PP_ImageDataDesc)); | 284 memcpy(&(*image_data_desc)[0], &desc, sizeof(PP_ImageDataDesc)); |
282 } | 285 } |
283 int local_fd; | 286 int local_fd; |
284 uint32_t byte_count; | 287 uint32_t byte_count; |
285 if (enter_resource.object()->GetSharedMemory(&local_fd, &byte_count) != PP_OK) | 288 if (enter_resource.object()->GetSharedMemory(&local_fd, &byte_count) != PP_OK) |
286 return; | 289 return; |
287 | |
288 // TODO(dmichael): Change trusted interface to return a PP_FileHandle, those | 290 // TODO(dmichael): Change trusted interface to return a PP_FileHandle, those |
289 // casts are ugly. | 291 // casts are ugly. |
290 base::PlatformFile platform_file = | 292 base::PlatformFile platform_file = |
291 #if defined(OS_WIN) | 293 #if defined(OS_WIN) |
292 reinterpret_cast<HANDLE>(static_cast<intptr_t>(local_fd)); | 294 reinterpret_cast<HANDLE>(static_cast<intptr_t>(local_fd)); |
293 #elif defined(OS_POSIX) | 295 #elif defined(OS_POSIX) |
294 local_fd; | 296 local_fd; |
295 #else | 297 #else |
296 #error Not implemented. | 298 #error Not implemented. |
297 #endif // defined(OS_WIN) | 299 #endif // defined(OS_WIN) |
298 *result_image_handle = | 300 result_image_handle->set_shmem( |
299 dispatcher->ShareHandleWithRemote(platform_file, false); | 301 dispatcher->ShareHandleWithRemote(platform_file, false), |
300 #endif // defined(OS_NACL) | 302 byte_count); |
| 303 #endif // defined(OS_NACL) || defined(NACL_WIN64) |
301 } | 304 } |
302 | 305 |
303 } // namespace proxy | 306 } // namespace proxy |
304 } // namespace ppapi | 307 } // namespace ppapi |
OLD | NEW |