[ServiceWorker] Implement WebServiceWorkerContextClient::openWindow().
[chromium-blink-merge.git] / content / renderer / pepper / ppb_image_data_impl.cc
blob21cf96b9c2f54586f72cf23243b2d9164e5e6744
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.
5 #include "content/renderer/pepper/ppb_image_data_impl.h"
7 #include <algorithm>
8 #include <limits>
10 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "content/common/view_messages.h"
13 #include "content/renderer/render_thread_impl.h"
14 #include "ppapi/c/pp_errors.h"
15 #include "ppapi/c/pp_instance.h"
16 #include "ppapi/c/pp_resource.h"
17 #include "ppapi/c/ppb_image_data.h"
18 #include "ppapi/thunk/thunk.h"
19 #include "skia/ext/platform_canvas.h"
20 #include "third_party/skia/include/core/SkColorPriv.h"
21 #include "ui/surface/transport_dib.h"
23 using ppapi::thunk::PPB_ImageData_API;
25 namespace content {
27 PPB_ImageData_Impl::PPB_ImageData_Impl(PP_Instance instance,
28 PPB_ImageData_Shared::ImageDataType type)
29 : Resource(ppapi::OBJECT_IS_IMPL, instance),
30 format_(PP_IMAGEDATAFORMAT_BGRA_PREMUL),
31 width_(0),
32 height_(0) {
33 switch (type) {
34 case PPB_ImageData_Shared::PLATFORM:
35 backend_.reset(new ImageDataPlatformBackend());
36 return;
37 case PPB_ImageData_Shared::SIMPLE:
38 backend_.reset(new ImageDataSimpleBackend);
39 return;
40 // No default: so that we get a compiler warning if any types are added.
42 NOTREACHED();
45 PPB_ImageData_Impl::PPB_ImageData_Impl(PP_Instance instance, ForTest)
46 : Resource(ppapi::OBJECT_IS_IMPL, instance),
47 format_(PP_IMAGEDATAFORMAT_BGRA_PREMUL),
48 width_(0),
49 height_(0) {
50 backend_.reset(new ImageDataPlatformBackend());
53 PPB_ImageData_Impl::~PPB_ImageData_Impl() {}
55 bool PPB_ImageData_Impl::Init(PP_ImageDataFormat format,
56 int width,
57 int height,
58 bool init_to_zero) {
59 // TODO(brettw) this should be called only on the main thread!
60 if (!IsImageDataFormatSupported(format))
61 return false; // Only support this one format for now.
62 if (width <= 0 || height <= 0)
63 return false;
64 if (static_cast<int64>(width) * static_cast<int64>(height) >=
65 std::numeric_limits<int32>::max() / 4)
66 return false; // Prevent overflow of signed 32-bit ints.
68 format_ = format;
69 width_ = width;
70 height_ = height;
71 return backend_->Init(this, format, width, height, init_to_zero);
74 // static
75 PP_Resource PPB_ImageData_Impl::Create(PP_Instance instance,
76 PPB_ImageData_Shared::ImageDataType type,
77 PP_ImageDataFormat format,
78 const PP_Size& size,
79 PP_Bool init_to_zero) {
80 scoped_refptr<PPB_ImageData_Impl> data(
81 new PPB_ImageData_Impl(instance, type));
82 if (!data->Init(format, size.width, size.height, !!init_to_zero))
83 return 0;
84 return data->GetReference();
87 PPB_ImageData_API* PPB_ImageData_Impl::AsPPB_ImageData_API() { return this; }
89 bool PPB_ImageData_Impl::IsMapped() const { return backend_->IsMapped(); }
91 TransportDIB* PPB_ImageData_Impl::GetTransportDIB() const {
92 return backend_->GetTransportDIB();
95 PP_Bool PPB_ImageData_Impl::Describe(PP_ImageDataDesc* desc) {
96 desc->format = format_;
97 desc->size.width = width_;
98 desc->size.height = height_;
99 desc->stride = width_ * 4;
100 return PP_TRUE;
103 void* PPB_ImageData_Impl::Map() { return backend_->Map(); }
105 void PPB_ImageData_Impl::Unmap() { backend_->Unmap(); }
107 int32_t PPB_ImageData_Impl::GetSharedMemory(int* handle, uint32_t* byte_count) {
108 return backend_->GetSharedMemory(handle, byte_count);
111 skia::PlatformCanvas* PPB_ImageData_Impl::GetPlatformCanvas() {
112 return backend_->GetPlatformCanvas();
115 SkCanvas* PPB_ImageData_Impl::GetCanvas() { return backend_->GetCanvas(); }
117 void PPB_ImageData_Impl::SetIsCandidateForReuse() {
118 // Nothing to do since we don't support image data re-use in-process.
121 const SkBitmap* PPB_ImageData_Impl::GetMappedBitmap() const {
122 return backend_->GetMappedBitmap();
125 // ImageDataPlatformBackend ----------------------------------------------------
127 ImageDataPlatformBackend::ImageDataPlatformBackend() : width_(0), height_(0) {
130 ImageDataPlatformBackend::~ImageDataPlatformBackend() {
133 bool ImageDataPlatformBackend::Init(PPB_ImageData_Impl* impl,
134 PP_ImageDataFormat format,
135 int width,
136 int height,
137 bool init_to_zero) {
138 // TODO(brettw) use init_to_zero when we implement caching.
139 width_ = width;
140 height_ = height;
141 uint32 buffer_size = width_ * height_ * 4;
142 scoped_ptr<base::SharedMemory> shared_memory =
143 RenderThread::Get()->HostAllocateSharedMemoryBuffer(buffer_size);
144 if (!shared_memory)
145 return false;
147 // The TransportDIB is always backed by shared memory, so give the shared
148 // memory handle to it.
149 base::SharedMemoryHandle handle;
150 if (!shared_memory->GiveToProcess(base::GetCurrentProcessHandle(), &handle))
151 return false;
153 dib_.reset(TransportDIB::CreateWithHandle(handle));
155 return !!dib_;
158 bool ImageDataPlatformBackend::IsMapped() const {
159 return !!mapped_canvas_.get();
162 TransportDIB* ImageDataPlatformBackend::GetTransportDIB() const {
163 return dib_.get();
166 void* ImageDataPlatformBackend::Map() {
167 if (!mapped_canvas_) {
168 mapped_canvas_.reset(dib_->GetPlatformCanvas(width_, height_));
169 if (!mapped_canvas_)
170 return NULL;
172 const SkBitmap& bitmap =
173 skia::GetTopDevice(*mapped_canvas_)->accessBitmap(true);
175 // Our platform bitmaps are set to opaque by default, which we don't want.
176 const_cast<SkBitmap&>(bitmap).setAlphaType(kPremul_SkAlphaType);
178 bitmap.lockPixels();
179 return bitmap.getAddr32(0, 0);
182 void ImageDataPlatformBackend::Unmap() {
183 // This is currently unimplemented, which is OK. The data will just always
184 // be around once it's mapped. Chrome's TransportDIB isn't currently
185 // unmappable without freeing it, but this may be something we want to support
186 // in the future to save some memory.
189 int32_t ImageDataPlatformBackend::GetSharedMemory(int* handle,
190 uint32_t* byte_count) {
191 *byte_count = dib_->size();
192 #if defined(OS_WIN)
193 *handle = reinterpret_cast<intptr_t>(dib_->handle());
194 #else
195 *handle = static_cast<intptr_t>(dib_->handle().fd);
196 #endif
198 return PP_OK;
201 skia::PlatformCanvas* ImageDataPlatformBackend::GetPlatformCanvas() {
202 return mapped_canvas_.get();
205 SkCanvas* ImageDataPlatformBackend::GetCanvas() { return mapped_canvas_.get(); }
207 const SkBitmap* ImageDataPlatformBackend::GetMappedBitmap() const {
208 if (!mapped_canvas_)
209 return NULL;
210 return &skia::GetTopDevice(*mapped_canvas_)->accessBitmap(false);
213 // ImageDataSimpleBackend ------------------------------------------------------
215 ImageDataSimpleBackend::ImageDataSimpleBackend() : map_count_(0) {}
217 ImageDataSimpleBackend::~ImageDataSimpleBackend() {}
219 bool ImageDataSimpleBackend::Init(PPB_ImageData_Impl* impl,
220 PP_ImageDataFormat format,
221 int width,
222 int height,
223 bool init_to_zero) {
224 skia_bitmap_.setInfo(
225 SkImageInfo::MakeN32Premul(impl->width(), impl->height()));
226 shared_memory_.reset(
227 RenderThread::Get()
228 ->HostAllocateSharedMemoryBuffer(skia_bitmap_.getSize())
229 .release());
230 return !!shared_memory_.get();
233 bool ImageDataSimpleBackend::IsMapped() const { return map_count_ > 0; }
235 TransportDIB* ImageDataSimpleBackend::GetTransportDIB() const { return NULL; }
237 void* ImageDataSimpleBackend::Map() {
238 DCHECK(shared_memory_.get());
239 if (map_count_++ == 0) {
240 shared_memory_->Map(skia_bitmap_.getSize());
241 skia_bitmap_.setPixels(shared_memory_->memory());
242 // Our platform bitmaps are set to opaque by default, which we don't want.
243 skia_bitmap_.setAlphaType(kPremul_SkAlphaType);
244 skia_canvas_.reset(new SkCanvas(skia_bitmap_));
245 return skia_bitmap_.getAddr32(0, 0);
247 return shared_memory_->memory();
250 void ImageDataSimpleBackend::Unmap() {
251 if (--map_count_ == 0)
252 shared_memory_->Unmap();
255 int32_t ImageDataSimpleBackend::GetSharedMemory(int* handle,
256 uint32_t* byte_count) {
257 *byte_count = skia_bitmap_.getSize();
258 #if defined(OS_POSIX)
259 *handle = shared_memory_->handle().fd;
260 #elif defined(OS_WIN)
261 *handle = reinterpret_cast<int>(shared_memory_->handle());
262 #else
263 #error "Platform not supported."
264 #endif
265 return PP_OK;
268 skia::PlatformCanvas* ImageDataSimpleBackend::GetPlatformCanvas() {
269 return NULL;
272 SkCanvas* ImageDataSimpleBackend::GetCanvas() {
273 if (!IsMapped())
274 return NULL;
275 return skia_canvas_.get();
278 const SkBitmap* ImageDataSimpleBackend::GetMappedBitmap() const {
279 if (!IsMapped())
280 return NULL;
281 return &skia_bitmap_;
284 } // namespace content