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

Side by Side Diff: ppapi/proxy/ppb_image_data_proxy.cc

Issue 10796064: PPAPI/NaCl: Make nacl_ipc_adapter handle ImageData creation (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Sketch of idea for extracting handles generally Created 8 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « ppapi/proxy/ppb_image_data_proxy.h ('k') | ppapi/proxy/resource_creation_proxy.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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)
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
OLDNEW
« no previous file with comments | « ppapi/proxy/ppb_image_data_proxy.h ('k') | ppapi/proxy/resource_creation_proxy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698