| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/c/trusted/ppb_image_data_trusted.h" | |
| 17 #include "ppapi/proxy/host_resource.h" | 16 #include "ppapi/proxy/host_resource.h" |
| 18 #include "ppapi/proxy/plugin_dispatcher.h" | 17 #include "ppapi/proxy/plugin_dispatcher.h" |
| 19 #include "ppapi/proxy/plugin_resource.h" | |
| 20 #include "ppapi/proxy/plugin_resource_tracker.h" | 18 #include "ppapi/proxy/plugin_resource_tracker.h" |
| 21 #include "ppapi/proxy/ppapi_messages.h" | 19 #include "ppapi/proxy/ppapi_messages.h" |
| 22 #include "ppapi/shared_impl/image_data_impl.h" | 20 #include "ppapi/thunk/thunk.h" |
| 23 | 21 |
| 24 #if defined(OS_LINUX) | 22 #if defined(OS_LINUX) |
| 25 #include <sys/shm.h> | 23 #include <sys/shm.h> |
| 26 #elif defined(OS_MACOSX) | 24 #elif defined(OS_MACOSX) |
| 27 #include <sys/stat.h> | 25 #include <sys/stat.h> |
| 28 #include <sys/mman.h> | 26 #include <sys/mman.h> |
| 29 #elif defined(OS_WIN) | 27 #elif defined(OS_WIN) |
| 30 #include <windows.h> | 28 #include <windows.h> |
| 31 #endif | 29 #endif |
| 32 | 30 |
| 33 namespace pp { | 31 namespace pp { |
| 34 namespace proxy { | 32 namespace proxy { |
| 35 | 33 |
| 36 class ImageData : public PluginResource, | 34 namespace { |
| 37 public pp::shared_impl::ImageDataImpl { | |
| 38 public: | |
| 39 ImageData(const HostResource& resource, | |
| 40 const PP_ImageDataDesc& desc, | |
| 41 ImageHandle handle); | |
| 42 virtual ~ImageData(); | |
| 43 | 35 |
| 44 // Resource overrides. | 36 InterfaceProxy* CreateImageDataProxy(Dispatcher* dispatcher, |
| 45 virtual ImageData* AsImageData(); | 37 const void* target_interface) { |
| 38 return new PPB_ImageData_Proxy(dispatcher, target_interface); |
| 39 } |
| 46 | 40 |
| 47 void* Map(); | 41 } // namespace |
| 48 void Unmap(); | |
| 49 | 42 |
| 50 const PP_ImageDataDesc& desc() const { return desc_; } | 43 // PPB_ImageData_Proxy --------------------------------------------------------- |
| 51 | 44 |
| 52 static const ImageHandle NullHandle; | 45 PPB_ImageData_Proxy::PPB_ImageData_Proxy(Dispatcher* dispatcher, |
| 53 static ImageHandle HandleFromInt(int32_t i); | 46 const void* target_interface) |
| 47 : InterfaceProxy(dispatcher, target_interface) { |
| 48 } |
| 54 | 49 |
| 55 private: | 50 PPB_ImageData_Proxy::~PPB_ImageData_Proxy() { |
| 56 PP_ImageDataDesc desc_; | 51 } |
| 57 ImageHandle handle_; | |
| 58 | 52 |
| 59 void* mapped_data_; | 53 // static |
| 54 const InterfaceProxy::Info* PPB_ImageData_Proxy::GetInfo() { |
| 55 static const Info info = { |
| 56 ::ppapi::thunk::GetPPB_ImageData_Thunk(), |
| 57 PPB_IMAGEDATA_INTERFACE, |
| 58 INTERFACE_ID_PPB_IMAGE_DATA, |
| 59 false, |
| 60 &CreateImageDataProxy, |
| 61 }; |
| 62 return &info; |
| 63 } |
| 60 | 64 |
| 61 DISALLOW_COPY_AND_ASSIGN(ImageData); | 65 bool PPB_ImageData_Proxy::OnMessageReceived(const IPC::Message& msg) { |
| 62 }; | 66 return false; |
| 67 } |
| 68 |
| 69 // ImageData ------------------------------------------------------------------- |
| 63 | 70 |
| 64 ImageData::ImageData(const HostResource& resource, | 71 ImageData::ImageData(const HostResource& resource, |
| 65 const PP_ImageDataDesc& desc, | 72 const PP_ImageDataDesc& desc, |
| 66 ImageHandle handle) | 73 ImageHandle handle) |
| 67 : PluginResource(resource), | 74 : PluginResource(resource), |
| 68 desc_(desc), | 75 desc_(desc), |
| 69 handle_(handle), | 76 handle_(handle), |
| 70 mapped_data_(NULL) { | 77 mapped_data_(NULL) { |
| 71 } | 78 } |
| 72 | 79 |
| 73 ImageData::~ImageData() { | 80 ImageData::~ImageData() { |
| 74 Unmap(); | 81 Unmap(); |
| 75 } | 82 } |
| 76 | 83 |
| 84 ::ppapi::thunk::PPB_ImageData_API* ImageData::AsImageData_API() { |
| 85 return this; |
| 86 } |
| 87 |
| 77 ImageData* ImageData::AsImageData() { | 88 ImageData* ImageData::AsImageData() { |
| 78 return this; | 89 return this; |
| 79 } | 90 } |
| 80 | 91 |
| 92 PP_Bool ImageData::Describe(PP_ImageDataDesc* desc) { |
| 93 memcpy(desc, &desc_, sizeof(PP_ImageDataDesc)); |
| 94 return PP_TRUE; |
| 95 } |
| 96 |
| 81 void* ImageData::Map() { | 97 void* ImageData::Map() { |
| 82 #if defined(OS_WIN) | 98 #if defined(OS_WIN) |
| 83 mapped_data_ = ::MapViewOfFile(handle_, FILE_MAP_READ | FILE_MAP_WRITE, | 99 mapped_data_ = ::MapViewOfFile(handle_, FILE_MAP_READ | FILE_MAP_WRITE, |
| 84 0, 0, 0); | 100 0, 0, 0); |
| 85 return mapped_data_; | 101 return mapped_data_; |
| 86 #elif defined(OS_MACOSX) | 102 #elif defined(OS_MACOSX) |
| 87 struct stat st; | 103 struct stat st; |
| 88 if (fstat(handle_.fd, &st) != 0) | 104 if (fstat(handle_.fd, &st) != 0) |
| 89 return NULL; | 105 return NULL; |
| 90 void* memory = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, | 106 void* memory = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 ImageHandle ImageData::HandleFromInt(int32_t i) { | 149 ImageHandle ImageData::HandleFromInt(int32_t i) { |
| 134 #if defined(OS_WIN) | 150 #if defined(OS_WIN) |
| 135 return reinterpret_cast<ImageHandle>(i); | 151 return reinterpret_cast<ImageHandle>(i); |
| 136 #elif defined(OS_MACOSX) | 152 #elif defined(OS_MACOSX) |
| 137 return ImageHandle(i, false); | 153 return ImageHandle(i, false); |
| 138 #else | 154 #else |
| 139 return static_cast<ImageHandle>(i); | 155 return static_cast<ImageHandle>(i); |
| 140 #endif | 156 #endif |
| 141 } | 157 } |
| 142 | 158 |
| 143 namespace { | |
| 144 | |
| 145 PP_ImageDataFormat GetNativeImageDataFormat() { | |
| 146 return ImageData::GetNativeImageDataFormat(); | |
| 147 } | |
| 148 | |
| 149 PP_Bool IsImageDataFormatSupported(PP_ImageDataFormat format) { | |
| 150 return BoolToPPBool(ImageData::IsImageDataFormatSupported(format)); | |
| 151 } | |
| 152 | |
| 153 PP_Resource Create(PP_Instance instance, | |
| 154 PP_ImageDataFormat format, | |
| 155 const PP_Size* size, | |
| 156 PP_Bool init_to_zero) { | |
| 157 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); | |
| 158 if (!dispatcher) | |
| 159 return 0; | |
| 160 | |
| 161 HostResource result; | |
| 162 std::string image_data_desc; | |
| 163 ImageHandle image_handle = ImageData::NullHandle; | |
| 164 dispatcher->Send(new PpapiHostMsg_PPBImageData_Create( | |
| 165 INTERFACE_ID_PPB_IMAGE_DATA, instance, format, *size, init_to_zero, | |
| 166 &result, &image_data_desc, &image_handle)); | |
| 167 | |
| 168 if (result.is_null() || image_data_desc.size() != sizeof(PP_ImageDataDesc)) | |
| 169 return 0; | |
| 170 | |
| 171 // We serialize the PP_ImageDataDesc just by copying to a string. | |
| 172 PP_ImageDataDesc desc; | |
| 173 memcpy(&desc, image_data_desc.data(), sizeof(PP_ImageDataDesc)); | |
| 174 | |
| 175 linked_ptr<ImageData> object(new ImageData(result, desc, image_handle)); | |
| 176 return PluginResourceTracker::GetInstance()->AddResource(object); | |
| 177 } | |
| 178 | |
| 179 PP_Bool IsImageData(PP_Resource resource) { | |
| 180 ImageData* object = PluginResource::GetAs<ImageData>(resource); | |
| 181 return BoolToPPBool(!!object); | |
| 182 } | |
| 183 | |
| 184 PP_Bool Describe(PP_Resource resource, PP_ImageDataDesc* desc) { | |
| 185 ImageData* object = PluginResource::GetAs<ImageData>(resource); | |
| 186 if (!object) | |
| 187 return PP_FALSE; | |
| 188 memcpy(desc, &object->desc(), sizeof(PP_ImageDataDesc)); | |
| 189 return PP_TRUE; | |
| 190 } | |
| 191 | |
| 192 void* Map(PP_Resource resource) { | |
| 193 ImageData* object = PluginResource::GetAs<ImageData>(resource); | |
| 194 if (!object) | |
| 195 return NULL; | |
| 196 return object->Map(); | |
| 197 } | |
| 198 | |
| 199 void Unmap(PP_Resource resource) { | |
| 200 ImageData* object = PluginResource::GetAs<ImageData>(resource); | |
| 201 if (object) | |
| 202 object->Unmap(); | |
| 203 } | |
| 204 | |
| 205 const PPB_ImageData image_data_interface = { | |
| 206 &GetNativeImageDataFormat, | |
| 207 &IsImageDataFormatSupported, | |
| 208 &Create, | |
| 209 &IsImageData, | |
| 210 &Describe, | |
| 211 &Map, | |
| 212 &Unmap, | |
| 213 }; | |
| 214 | |
| 215 InterfaceProxy* CreateImageDataProxy(Dispatcher* dispatcher, | |
| 216 const void* target_interface) { | |
| 217 return new PPB_ImageData_Proxy(dispatcher, target_interface); | |
| 218 } | |
| 219 | |
| 220 } // namespace | |
| 221 | |
| 222 PPB_ImageData_Proxy::PPB_ImageData_Proxy(Dispatcher* dispatcher, | |
| 223 const void* target_interface) | |
| 224 : InterfaceProxy(dispatcher, target_interface) { | |
| 225 } | |
| 226 | |
| 227 PPB_ImageData_Proxy::~PPB_ImageData_Proxy() { | |
| 228 } | |
| 229 | |
| 230 // static | |
| 231 const InterfaceProxy::Info* PPB_ImageData_Proxy::GetInfo() { | |
| 232 static const Info info = { | |
| 233 &image_data_interface, | |
| 234 PPB_IMAGEDATA_INTERFACE, | |
| 235 INTERFACE_ID_PPB_IMAGE_DATA, | |
| 236 false, | |
| 237 &CreateImageDataProxy, | |
| 238 }; | |
| 239 return &info; | |
| 240 } | |
| 241 | |
| 242 bool PPB_ImageData_Proxy::OnMessageReceived(const IPC::Message& msg) { | |
| 243 bool handled = true; | |
| 244 IPC_BEGIN_MESSAGE_MAP(PPB_ImageData_Proxy, msg) | |
| 245 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBImageData_Create, OnMsgCreate) | |
| 246 IPC_MESSAGE_UNHANDLED(handled = false) | |
| 247 IPC_END_MESSAGE_MAP() | |
| 248 // FIXME(brettw) handle bad messages! | |
| 249 return handled; | |
| 250 } | |
| 251 | |
| 252 void PPB_ImageData_Proxy::OnMsgCreate(PP_Instance instance, | |
| 253 int32_t format, | |
| 254 const PP_Size& size, | |
| 255 PP_Bool init_to_zero, | |
| 256 HostResource* result, | |
| 257 std::string* image_data_desc, | |
| 258 ImageHandle* result_image_handle) { | |
| 259 PP_Resource resource = ppb_image_data_target()->Create( | |
| 260 instance, static_cast<PP_ImageDataFormat>(format), &size, init_to_zero); | |
| 261 *result_image_handle = ImageData::NullHandle; | |
| 262 if (resource) { | |
| 263 // The ImageDesc is just serialized as a string. | |
| 264 PP_ImageDataDesc desc; | |
| 265 if (ppb_image_data_target()->Describe(resource, &desc)) { | |
| 266 image_data_desc->resize(sizeof(PP_ImageDataDesc)); | |
| 267 memcpy(&(*image_data_desc)[0], &desc, sizeof(PP_ImageDataDesc)); | |
| 268 } | |
| 269 | |
| 270 // Get the shared memory handle. | |
| 271 const PPB_ImageDataTrusted* trusted = | |
| 272 reinterpret_cast<const PPB_ImageDataTrusted*>( | |
| 273 dispatcher()->GetLocalInterface(PPB_IMAGEDATA_TRUSTED_INTERFACE)); | |
| 274 uint32_t byte_count = 0; | |
| 275 if (trusted) { | |
| 276 int32_t handle; | |
| 277 if (trusted->GetSharedMemory(resource, &handle, &byte_count) == PP_OK) { | |
| 278 #if defined(OS_WIN) | |
| 279 pp::proxy::ImageHandle ih = ImageData::HandleFromInt(handle); | |
| 280 *result_image_handle = dispatcher()->ShareHandleWithRemote(ih, false); | |
| 281 #else | |
| 282 // TODO: This memory sharing is probaly broken on Mac. | |
| 283 *result_image_handle = ImageData::HandleFromInt(handle); | |
| 284 #endif | |
| 285 } | |
| 286 } | |
| 287 | |
| 288 result->SetHostResource(instance, resource); | |
| 289 } | |
| 290 } | |
| 291 | |
| 292 } // namespace proxy | 159 } // namespace proxy |
| 293 } // namespace pp | 160 } // namespace pp |
| OLD | NEW |