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