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