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