| Index: ppapi/proxy/ppb_image_data_proxy.cc | 
| =================================================================== | 
| --- ppapi/proxy/ppb_image_data_proxy.cc	(revision 72840) | 
| +++ ppapi/proxy/ppb_image_data_proxy.cc	(working copy) | 
| @@ -14,14 +14,128 @@ | 
| #include "ppapi/c/pp_errors.h" | 
| #include "ppapi/c/pp_resource.h" | 
| #include "ppapi/c/trusted/ppb_image_data_trusted.h" | 
| -#include "ppapi/proxy/image_data.h" | 
| +#include "ppapi/proxy/host_resource.h" | 
| #include "ppapi/proxy/plugin_dispatcher.h" | 
| +#include "ppapi/proxy/plugin_resource.h" | 
| #include "ppapi/proxy/plugin_resource_tracker.h" | 
| #include "ppapi/proxy/ppapi_messages.h" | 
| +#include "ppapi/shared_impl/image_data_impl.h" | 
|  | 
| +#if defined(OS_LINUX) | 
| +#include <sys/shm.h> | 
| +#elif defined(OS_MACOSX) | 
| +#include <sys/stat.h> | 
| +#include <sys/mman.h> | 
| +#endif | 
| + | 
| namespace pp { | 
| namespace proxy { | 
|  | 
| +class ImageData : public PluginResource, | 
| +                  public pp::shared_impl::ImageDataImpl { | 
| + public: | 
| +  ImageData(const HostResource& resource, | 
| +            const PP_ImageDataDesc& desc, | 
| +            ImageHandle handle); | 
| +  virtual ~ImageData(); | 
| + | 
| +  // Resource overrides. | 
| +  virtual ImageData* AsImageData(); | 
| + | 
| +  void* Map(); | 
| +  void Unmap(); | 
| + | 
| +  const PP_ImageDataDesc& desc() const { return desc_; } | 
| + | 
| +  static const ImageHandle NullHandle; | 
| +  static ImageHandle HandleFromInt(int32_t i); | 
| + | 
| + private: | 
| +  PP_ImageDataDesc desc_; | 
| +  ImageHandle handle_; | 
| + | 
| +  void* mapped_data_; | 
| + | 
| +  DISALLOW_COPY_AND_ASSIGN(ImageData); | 
| +}; | 
| + | 
| +ImageData::ImageData(const HostResource& resource, | 
| +                     const PP_ImageDataDesc& desc, | 
| +                     ImageHandle handle) | 
| +    : PluginResource(resource), | 
| +      desc_(desc), | 
| +      handle_(handle), | 
| +      mapped_data_(NULL) { | 
| +} | 
| + | 
| +ImageData::~ImageData() { | 
| +  Unmap(); | 
| +} | 
| + | 
| +ImageData* ImageData::AsImageData() { | 
| +  return this; | 
| +} | 
| + | 
| +void* ImageData::Map() { | 
| +#if defined(OS_WIN) | 
| +  NOTIMPLEMENTED(); | 
| +  return NULL; | 
| +#elif defined(OS_MACOSX) | 
| +  struct stat st; | 
| +  if (fstat(handle_.fd, &st) != 0) | 
| +    return NULL; | 
| +  void* memory = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, | 
| +                      MAP_SHARED, handle_.fd, 0); | 
| +  if (memory == MAP_FAILED) | 
| +    return NULL; | 
| +  mapped_data_ = memory; | 
| +  return mapped_data_; | 
| +#else | 
| +  int shmkey = handle_; | 
| +  void* address = shmat(shmkey, NULL, 0); | 
| +  // Mark for deletion in case we crash so the kernel will clean it up. | 
| +  shmctl(shmkey, IPC_RMID, 0); | 
| +  if (address == (void*)-1) | 
| +    return NULL; | 
| +  mapped_data_ = address; | 
| +  return address; | 
| +#endif | 
| +} | 
| + | 
| +void ImageData::Unmap() { | 
| +#if defined(OS_WIN) | 
| +  NOTIMPLEMENTED(); | 
| +#elif defined(OS_MACOSX) | 
| +  if (mapped_data_) { | 
| +    struct stat st; | 
| +    if (fstat(handle_.fd, &st) == 0) | 
| +      munmap(mapped_data_, st.st_size); | 
| +  } | 
| +#else | 
| +  if (mapped_data_) | 
| +    shmdt(mapped_data_); | 
| +#endif | 
| +  mapped_data_ = NULL; | 
| +} | 
| + | 
| +#if defined(OS_WIN) | 
| +const ImageHandle ImageData::NullHandle = NULL; | 
| +#elif defined(OS_MACOSX) | 
| +const ImageHandle ImageData::NullHandle = ImageHandle(); | 
| +#else | 
| +const ImageHandle ImageData::NullHandle = 0; | 
| +#endif | 
| + | 
| +ImageHandle ImageData::HandleFromInt(int32_t i) { | 
| +#if defined(OS_WIN) | 
| +    return reinterpret_cast<ImageHandle>(i); | 
| +#elif defined(OS_MACOSX) | 
| +    return ImageHandle(i, false); | 
| +#else | 
| +    return static_cast<ImageHandle>(i); | 
| +#endif | 
| +} | 
| + | 
| namespace { | 
|  | 
| PP_ImageDataFormat GetNativeImageDataFormat() { | 
| @@ -40,22 +154,22 @@ | 
| if (!dispatcher) | 
| return PP_ERROR_BADARGUMENT; | 
|  | 
| -  PP_Resource result = 0; | 
| +  HostResource result; | 
| std::string image_data_desc; | 
| ImageHandle image_handle = ImageData::NullHandle; | 
| dispatcher->Send(new PpapiHostMsg_PPBImageData_Create( | 
| INTERFACE_ID_PPB_IMAGE_DATA, instance, format, *size, init_to_zero, | 
| &result, &image_data_desc, &image_handle)); | 
|  | 
| -  if (result && image_data_desc.size() == sizeof(PP_ImageDataDesc)) { | 
| -    // We serialize the PP_ImageDataDesc just by copying to a string. | 
| -    PP_ImageDataDesc desc; | 
| -    memcpy(&desc, image_data_desc.data(), sizeof(PP_ImageDataDesc)); | 
| +  if (result.is_null() || image_data_desc.size() != sizeof(PP_ImageDataDesc)) | 
| +    return 0; | 
|  | 
| -    linked_ptr<ImageData> object(new ImageData(instance, desc, image_handle)); | 
| -    PluginResourceTracker::GetInstance()->AddResource(result, object); | 
| -  } | 
| -  return result; | 
| +  // We serialize the PP_ImageDataDesc just by copying to a string. | 
| +  PP_ImageDataDesc desc; | 
| +  memcpy(&desc, image_data_desc.data(), sizeof(PP_ImageDataDesc)); | 
| + | 
| +  linked_ptr<ImageData> object(new ImageData(result, desc, image_handle)); | 
| +  return PluginResourceTracker::GetInstance()->AddResource(object); | 
| } | 
|  | 
| PP_Bool IsImageData(PP_Resource resource) { | 
| @@ -126,16 +240,16 @@ | 
| int32_t format, | 
| const PP_Size& size, | 
| PP_Bool init_to_zero, | 
| -                                      PP_Resource* result, | 
| +                                      HostResource* result, | 
| std::string* image_data_desc, | 
| ImageHandle* result_image_handle) { | 
| -  *result = ppb_image_data_target()->Create( | 
| +  PP_Resource resource = ppb_image_data_target()->Create( | 
| instance, static_cast<PP_ImageDataFormat>(format), &size, init_to_zero); | 
| *result_image_handle = ImageData::NullHandle; | 
| -  if (*result) { | 
| +  if (resource) { | 
| // The ImageDesc is just serialized as a string. | 
| PP_ImageDataDesc desc; | 
| -    if (ppb_image_data_target()->Describe(*result, &desc)) { | 
| +    if (ppb_image_data_target()->Describe(resource, &desc)) { | 
| image_data_desc->resize(sizeof(PP_ImageDataDesc)); | 
| memcpy(&(*image_data_desc)[0], &desc, sizeof(PP_ImageDataDesc)); | 
| } | 
| @@ -147,9 +261,11 @@ | 
| uint32_t byte_count = 0; | 
| if (trusted) { | 
| int32_t handle; | 
| -      if (trusted->GetSharedMemory(*result, &handle, &byte_count) == PP_OK) | 
| +      if (trusted->GetSharedMemory(resource, &handle, &byte_count) == PP_OK) | 
| *result_image_handle = ImageData::HandleFromInt(handle); | 
| } | 
| + | 
| +    result->SetHostResource(instance, resource); | 
| } | 
| } | 
|  | 
|  |