Home | History | Annotate | Download | only in pepper
      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
      3 // found in the LICENSE file.
      4 
      5 #ifndef CONTENT_RENDERER_PEPPER_PPB_IMAGE_DATA_IMPL_H_
      6 #define CONTENT_RENDERER_PEPPER_PPB_IMAGE_DATA_IMPL_H_
      7 
      8 #include "base/basictypes.h"
      9 #include "base/memory/scoped_ptr.h"
     10 #include "content/common/content_export.h"
     11 #include "ppapi/c/ppb_image_data.h"
     12 #include "ppapi/shared_impl/ppb_image_data_shared.h"
     13 #include "ppapi/shared_impl/resource.h"
     14 #include "ppapi/thunk/ppb_image_data_api.h"
     15 #include "third_party/skia/include/core/SkCanvas.h"
     16 
     17 class SkBitmap;
     18 class SkCanvas;
     19 class TransportDIB;
     20 
     21 namespace base {
     22 class SharedMemory;
     23 }
     24 
     25 namespace content {
     26 
     27 class CONTENT_EXPORT PPB_ImageData_Impl
     28     : public ppapi::Resource,
     29       public ppapi::PPB_ImageData_Shared,
     30       public NON_EXPORTED_BASE(ppapi::thunk::PPB_ImageData_API) {
     31  public:
     32   // We delegate most of our implementation to a back-end class that either uses
     33   // a PlatformCanvas (for most trusted stuff) or bare shared memory (for use by
     34   // NaCl, or trusted plugins when the PlatformCanvas isn't needed). This makes
     35   // it cheap & easy to implement Swap.
     36   class Backend {
     37    public:
     38     virtual ~Backend() {};
     39     virtual bool Init(PPB_ImageData_Impl* impl, PP_ImageDataFormat format,
     40                       int width, int height, bool init_to_zero) = 0;
     41     virtual bool IsMapped() const = 0;
     42     virtual TransportDIB* GetTransportDIB() const = 0;
     43     virtual void* Map() = 0;
     44     virtual void Unmap() = 0;
     45     virtual int32_t GetSharedMemory(int* handle, uint32_t* byte_count) = 0;
     46     virtual SkCanvas* GetPlatformCanvas() = 0;
     47     virtual SkCanvas* GetCanvas() = 0;
     48     virtual const SkBitmap* GetMappedBitmap() const = 0;
     49   };
     50 
     51   // If you call this constructor, you must also call Init before use. Normally
     52   // you should use the static Create function, but this constructor is needed
     53   // for some internal uses of ImageData (like Graphics2D).
     54   PPB_ImageData_Impl(PP_Instance instance,
     55                      PPB_ImageData_Shared::ImageDataType type);
     56 
     57   // Constructor used for unittests. The ImageData is always allocated locally.
     58   struct ForTest {};
     59   PPB_ImageData_Impl(PP_Instance instance,
     60                      ForTest);
     61 
     62   bool Init(PP_ImageDataFormat format,
     63             int width, int height,
     64             bool init_to_zero);
     65 
     66   static PP_Resource Create(PP_Instance pp_instance,
     67                             PPB_ImageData_Shared::ImageDataType type,
     68                             PP_ImageDataFormat format,
     69                             const PP_Size& size,
     70                             PP_Bool init_to_zero);
     71 
     72   int width() const { return width_; }
     73   int height() const { return height_; }
     74 
     75   // Returns the image format.
     76   PP_ImageDataFormat format() const { return format_; }
     77 
     78   // Returns true if this image is mapped. False means that the image is either
     79   // invalid or not mapped. See ImageDataAutoMapper below.
     80   bool IsMapped() const;
     81   TransportDIB* GetTransportDIB() const;
     82 
     83   // Resource override.
     84   virtual ppapi::thunk::PPB_ImageData_API* AsPPB_ImageData_API() OVERRIDE;
     85 
     86   // PPB_ImageData_API implementation.
     87   virtual PP_Bool Describe(PP_ImageDataDesc* desc) OVERRIDE;
     88   virtual void* Map() OVERRIDE;
     89   virtual void Unmap() OVERRIDE;
     90   virtual int32_t GetSharedMemory(int* handle, uint32_t* byte_count) OVERRIDE;
     91   virtual SkCanvas* GetPlatformCanvas() OVERRIDE;
     92   virtual SkCanvas* GetCanvas() OVERRIDE;
     93   virtual void SetIsCandidateForReuse() OVERRIDE;
     94 
     95   const SkBitmap* GetMappedBitmap() const;
     96 
     97  private:
     98   virtual ~PPB_ImageData_Impl();
     99 
    100   PP_ImageDataFormat format_;
    101   int width_;
    102   int height_;
    103   scoped_ptr<Backend> backend_;
    104 
    105   DISALLOW_COPY_AND_ASSIGN(PPB_ImageData_Impl);
    106 };
    107 
    108 class ImageDataPlatformBackend : public PPB_ImageData_Impl::Backend {
    109  public:
    110   // |is_browser_allocated| indicates whether the backing shared memory should
    111   // be allocated by the browser process.
    112   ImageDataPlatformBackend(bool is_browser_allocated);
    113   virtual ~ImageDataPlatformBackend();
    114 
    115   // PPB_ImageData_Impl::Backend implementation.
    116   virtual bool Init(PPB_ImageData_Impl* impl, PP_ImageDataFormat format,
    117                     int width, int height, bool init_to_zero) OVERRIDE;
    118   virtual bool IsMapped() const OVERRIDE;
    119   virtual TransportDIB* GetTransportDIB() const OVERRIDE;
    120   virtual void* Map() OVERRIDE;
    121   virtual void Unmap() OVERRIDE;
    122   virtual int32_t GetSharedMemory(int* handle, uint32_t* byte_count) OVERRIDE;
    123   virtual SkCanvas* GetPlatformCanvas() OVERRIDE;
    124   virtual SkCanvas* GetCanvas() OVERRIDE;
    125   virtual const SkBitmap* GetMappedBitmap() const OVERRIDE;
    126 
    127  private:
    128   // This will be NULL before initialization, and if this PPB_ImageData_Impl is
    129   // swapped with another.
    130   int width_;
    131   int height_;
    132   scoped_ptr<TransportDIB> dib_;
    133 
    134   bool is_browser_allocated_;
    135 
    136   // When the device is mapped, this is the image. Null when umapped.
    137   scoped_ptr<SkCanvas> mapped_canvas_;
    138 
    139   DISALLOW_COPY_AND_ASSIGN(ImageDataPlatformBackend);
    140 };
    141 
    142 class ImageDataSimpleBackend : public PPB_ImageData_Impl::Backend {
    143  public:
    144   ImageDataSimpleBackend();
    145   virtual ~ImageDataSimpleBackend();
    146 
    147   // PPB_ImageData_Impl::Backend implementation.
    148   virtual bool Init(PPB_ImageData_Impl* impl, PP_ImageDataFormat format,
    149             int width, int height, bool init_to_zero) OVERRIDE;
    150   virtual bool IsMapped() const OVERRIDE;
    151   virtual TransportDIB* GetTransportDIB() const OVERRIDE;
    152   virtual void* Map() OVERRIDE;
    153   virtual void Unmap() OVERRIDE;
    154   virtual int32_t GetSharedMemory(int* handle, uint32_t* byte_count) OVERRIDE;
    155   virtual SkCanvas* GetPlatformCanvas() OVERRIDE;
    156   virtual SkCanvas* GetCanvas() OVERRIDE;
    157   virtual const SkBitmap* GetMappedBitmap() const OVERRIDE;
    158 
    159  private:
    160   scoped_ptr<base::SharedMemory> shared_memory_;
    161   // skia_bitmap_ is backed by shared_memory_.
    162   SkBitmap skia_bitmap_;
    163   scoped_ptr<SkCanvas> skia_canvas_;
    164   uint32 map_count_;
    165 
    166   DISALLOW_COPY_AND_ASSIGN(ImageDataSimpleBackend);
    167 };
    168 
    169 // Manages mapping an image resource if necessary. Use this to ensure the
    170 // image is mapped. The destructor will put the image back into the previous
    171 // state. You must check is_valid() to make sure the image was successfully
    172 // mapped before using it.
    173 //
    174 // Example:
    175 //   ImageDataAutoMapper mapper(image_data);
    176 //   if (!mapper.is_valid())
    177 //     return utter_failure;
    178 //   image_data->mapped_canvas()->blah();  // Guaranteed valid.
    179 class ImageDataAutoMapper {
    180  public:
    181   explicit ImageDataAutoMapper(PPB_ImageData_Impl* image_data)
    182         : image_data_(image_data) {
    183     if (image_data_->IsMapped()) {
    184       is_valid_ = true;
    185       needs_unmap_ = false;
    186     } else {
    187       is_valid_ = needs_unmap_ = !!image_data_->Map();
    188     }
    189   }
    190 
    191   ~ImageDataAutoMapper() {
    192     if (needs_unmap_)
    193       image_data_->Unmap();
    194   }
    195 
    196   // Check this to see if the image was successfully mapped. If this is false,
    197   // the image could not be mapped and is unusable.
    198   bool is_valid() const { return is_valid_; }
    199 
    200  private:
    201   PPB_ImageData_Impl* image_data_;
    202   bool is_valid_;
    203   bool needs_unmap_;
    204 
    205   DISALLOW_COPY_AND_ASSIGN(ImageDataAutoMapper);
    206 };
    207 
    208 }  // namespace content
    209 
    210 #endif  // CONTENT_RENDERER_PEPPER_PPB_IMAGE_DATA_IMPL_H_
    211