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