ppb_image_data_impl.cc revision f2477e01787aa58f445919b809d89e252beef54f
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/renderer/pepper/ppb_image_data_impl.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <limits>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
12558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/common/view_messages.h"
13bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/renderer/pepper/common.h"
14558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/renderer/render_thread_impl.h"
15d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "ppapi/c/pp_errors.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_instance.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_resource.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/ppb_image_data.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/thunk/thunk.h"
20d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "skia/ext/platform_canvas.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkColorPriv.h"
22558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "ui/surface/transport_dib.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochusing ppapi::thunk::PPB_ImageData_API;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2658e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdochnamespace content {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace {
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Returns true if the ImageData shared memory should be allocated in the
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// browser process for the current platform.
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool IsBrowserAllocated() {
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_POSIX) && !defined(TOOLKIT_GTK) && !defined(OS_ANDROID)
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // On the Mac, shared memory has to be created in the browser in order to
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // work in the sandbox.
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return true;
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return false;
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_ImageData_Impl::PPB_ImageData_Impl(PP_Instance instance,
427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                       PPB_ImageData_Shared::ImageDataType type)
43ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    : Resource(ppapi::OBJECT_IS_IMPL, instance),
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      format_(PP_IMAGEDATAFORMAT_BGRA_PREMUL),
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      width_(0),
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      height_(0) {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (type) {
487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case PPB_ImageData_Shared::PLATFORM:
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      backend_.reset(new ImageDataPlatformBackend(IsBrowserAllocated()));
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case PPB_ImageData_Shared::SIMPLE:
527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      backend_.reset(new ImageDataSimpleBackend);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No default: so that we get a compiler warning if any types are added.
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)PPB_ImageData_Impl::PPB_ImageData_Impl(PP_Instance instance,
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                       ForTest)
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    : Resource(ppapi::OBJECT_IS_IMPL, instance),
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      format_(PP_IMAGEDATAFORMAT_BGRA_PREMUL),
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      width_(0),
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      height_(0) {
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    backend_.reset(new ImageDataPlatformBackend(false));
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_ImageData_Impl::~PPB_ImageData_Impl() {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PPB_ImageData_Impl::Init(PP_ImageDataFormat format,
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              int width, int height,
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              bool init_to_zero) {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(brettw) this should be called only on the main thread!
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsImageDataFormatSupported(format))
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;  // Only support this one format for now.
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (width <= 0 || height <= 0)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (static_cast<int64>(width) * static_cast<int64>(height) >=
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      std::numeric_limits<int32>::max() / 4)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;  // Prevent overflow of signed 32-bit ints.
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  format_ = format;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  width_ = width;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  height_ = height;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return backend_->Init(this, format, width, height, init_to_zero);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)PP_Resource PPB_ImageData_Impl::Create(PP_Instance instance,
917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                       PPB_ImageData_Shared::ImageDataType type,
927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                       PP_ImageDataFormat format,
937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                       const PP_Size& size,
947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                       PP_Bool init_to_zero) {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<PPB_ImageData_Impl>
967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      data(new PPB_ImageData_Impl(instance, type));
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!data->Init(format, size.width, size.height, !!init_to_zero))
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return data->GetReference();
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_ImageData_API* PPB_ImageData_Impl::AsPPB_ImageData_API() {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return this;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PPB_ImageData_Impl::IsMapped() const {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return backend_->IsMapped();
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTransportDIB* PPB_ImageData_Impl::GetTransportDIB() const {
111558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return backend_->GetTransportDIB();
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Bool PPB_ImageData_Impl::Describe(PP_ImageDataDesc* desc) {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  desc->format = format_;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  desc->size.width = width_;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  desc->size.height = height_;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  desc->stride = width_ * 4;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_TRUE;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* PPB_ImageData_Impl::Map() {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return backend_->Map();
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PPB_ImageData_Impl::Unmap() {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->Unmap();
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t PPB_ImageData_Impl::GetSharedMemory(int* handle, uint32_t* byte_count) {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return backend_->GetSharedMemory(handle, byte_count);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)skia::PlatformCanvas* PPB_ImageData_Impl::GetPlatformCanvas() {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return backend_->GetPlatformCanvas();
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkCanvas* PPB_ImageData_Impl::GetCanvas() {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return backend_->GetCanvas();
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void PPB_ImageData_Impl::SetIsCandidateForReuse() {
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Nothing to do since we don't support image data re-use in-process.
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkBitmap* PPB_ImageData_Impl::GetMappedBitmap() const {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return backend_->GetMappedBitmap();
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// ImageDataPlatformBackend ----------------------------------------------------
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ImageDataPlatformBackend::ImageDataPlatformBackend(bool is_browser_allocated)
153558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    : width_(0),
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      height_(0),
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      is_browser_allocated_(is_browser_allocated) {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
158558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// On POSIX, we have to tell the browser to free the transport DIB.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageDataPlatformBackend::~ImageDataPlatformBackend() {
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (is_browser_allocated_) {
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_POSIX)
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (dib_) {
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      RenderThreadImpl::current()->Send(
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          new ViewHostMsg_FreeTransportDIB(dib_->id()));
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
166558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#endif
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ImageDataPlatformBackend::Init(PPB_ImageData_Impl* impl,
171558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                    PP_ImageDataFormat format,
172558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                    int width, int height,
173558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                    bool init_to_zero) {
174558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // TODO(brettw) use init_to_zero when we implement caching.
175558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  width_ = width;
176558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  height_ = height;
177558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  uint32 buffer_size = width_ * height_ * 4;
178558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
179558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Allocate the transport DIB and the PlatformCanvas pointing to it.
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  TransportDIB* dib = NULL;
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (is_browser_allocated_) {
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_POSIX)
183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Allocate the image data by sending a message to the browser requesting a
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // TransportDIB (see also chrome/renderer/webplugin_delegate_proxy.cc,
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // method WebPluginDelegateProxy::CreateBitmap() for similar code). The
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // TransportDIB is cached in the browser, and is freed (in typical cases) by
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // the TransportDIB's destructor.
188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    TransportDIB::Handle dib_handle;
189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    IPC::Message* msg = new ViewHostMsg_AllocTransportDIB(buffer_size,
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                                          true,
191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                                          &dib_handle);
192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!RenderThreadImpl::current()->Send(msg))
193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return false;
194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!TransportDIB::is_valid_handle(dib_handle))
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return false;
196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    dib = TransportDIB::CreateWithHandle(dib_handle);
198558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#endif
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else {
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    static int next_dib_id = 0;
201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    dib = TransportDIB::Create(buffer_size, next_dib_id++);
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!dib)
203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return false;
204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(dib);
206558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  dib_.reset(dib);
207558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return true;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ImageDataPlatformBackend::IsMapped() const {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return !!mapped_canvas_.get();
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
214558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTransportDIB* ImageDataPlatformBackend::GetTransportDIB() const {
215558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return dib_.get();
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* ImageDataPlatformBackend::Map() {
219b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (!mapped_canvas_) {
220558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    mapped_canvas_.reset(dib_->GetPlatformCanvas(width_, height_));
221b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    if (!mapped_canvas_)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return NULL;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const SkBitmap& bitmap =
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      skia::GetTopDevice(*mapped_canvas_)->accessBitmap(true);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Our platform bitmaps are set to opaque by default, which we don't want.
2281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const_cast<SkBitmap&>(bitmap).setAlphaType(kPremul_SkAlphaType);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap.lockPixels();
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bitmap.getAddr32(0, 0);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ImageDataPlatformBackend::Unmap() {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is currently unimplemented, which is OK. The data will just always
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be around once it's mapped. Chrome's TransportDIB isn't currently
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // unmappable without freeing it, but this may be something we want to support
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in the future to save some memory.
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t ImageDataPlatformBackend::GetSharedMemory(int* handle,
242558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                                  uint32_t* byte_count) {
243558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  *byte_count = dib_->size();
244558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#if defined(OS_WIN)
245558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  *handle = reinterpret_cast<intptr_t>(dib_->handle());
246558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#elif defined(TOOLKIT_GTK)
247558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  *handle = static_cast<intptr_t>(dib_->handle());
248558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#else
249558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  *handle = static_cast<intptr_t>(dib_->handle().fd);
250558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#endif
251558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_OK;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)skia::PlatformCanvas* ImageDataPlatformBackend::GetPlatformCanvas() {
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return mapped_canvas_.get();
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkCanvas* ImageDataPlatformBackend::GetCanvas() {
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return mapped_canvas_.get();
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkBitmap* ImageDataPlatformBackend::GetMappedBitmap() const {
264b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (!mapped_canvas_)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return &skia::GetTopDevice(*mapped_canvas_)->accessBitmap(false);
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// ImageDataSimpleBackend ------------------------------------------------------
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)ImageDataSimpleBackend::ImageDataSimpleBackend()
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : map_count_(0) {
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)ImageDataSimpleBackend::~ImageDataSimpleBackend() {
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool ImageDataSimpleBackend::Init(PPB_ImageData_Impl* impl,
2797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  PP_ImageDataFormat format,
2807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  int width, int height,
2817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  bool init_to_zero) {
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  skia_bitmap_.setConfig(SkBitmap::kARGB_8888_Config,
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         impl->width(), impl->height());
284558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  shared_memory_.reset(RenderThread::Get()->HostAllocateSharedMemoryBuffer(
285558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      skia_bitmap_.getSize()).release());
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return !!shared_memory_.get();
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool ImageDataSimpleBackend::IsMapped() const {
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return map_count_ > 0;
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
293558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTransportDIB* ImageDataSimpleBackend::GetTransportDIB() const {
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void* ImageDataSimpleBackend::Map() {
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(shared_memory_.get());
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (map_count_++ == 0) {
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    shared_memory_->Map(skia_bitmap_.getSize());
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skia_bitmap_.setPixels(shared_memory_->memory());
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Our platform bitmaps are set to opaque by default, which we don't want.
3031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    skia_bitmap_.setAlphaType(kPremul_SkAlphaType);
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skia_canvas_.reset(new SkCanvas(skia_bitmap_));
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return skia_bitmap_.getAddr32(0, 0);
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return shared_memory_->memory();
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void ImageDataSimpleBackend::Unmap() {
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (--map_count_ == 0)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    shared_memory_->Unmap();
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)int32_t ImageDataSimpleBackend::GetSharedMemory(int* handle,
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                uint32_t* byte_count) {
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *byte_count = skia_bitmap_.getSize();
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *handle = shared_memory_->handle().fd;
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_WIN)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *handle = reinterpret_cast<int>(shared_memory_->handle());
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#error "Platform not supported."
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_OK;
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)skia::PlatformCanvas* ImageDataSimpleBackend::GetPlatformCanvas() {
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)SkCanvas* ImageDataSimpleBackend::GetCanvas() {
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsMapped())
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return skia_canvas_.get();
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)const SkBitmap* ImageDataSimpleBackend::GetMappedBitmap() const {
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsMapped())
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return &skia_bitmap_;
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34458e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch}  // namespace content
345