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"
13558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/renderer/render_thread_impl.h"
14d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "ppapi/c/pp_errors.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_instance.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_resource.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/ppb_image_data.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/thunk/thunk.h"
19d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "skia/ext/platform_canvas.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkColorPriv.h"
21558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "ui/surface/transport_dib.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochusing ppapi::thunk::PPB_ImageData_API;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdochnamespace content {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace {
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Returns true if the ImageData shared memory should be allocated in the
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// browser process for the current platform.
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool IsBrowserAllocated() {
31a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#if defined(OS_POSIX) && !defined(OS_ANDROID)
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // On the Mac, shared memory has to be created in the browser in order to
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // work in the sandbox.
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return true;
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return false;
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_ImageData_Impl::PPB_ImageData_Impl(PP_Instance instance,
417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                       PPB_ImageData_Shared::ImageDataType type)
42ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    : Resource(ppapi::OBJECT_IS_IMPL, instance),
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      format_(PP_IMAGEDATAFORMAT_BGRA_PREMUL),
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      width_(0),
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      height_(0) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (type) {
477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case PPB_ImageData_Shared::PLATFORM:
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      backend_.reset(new ImageDataPlatformBackend(IsBrowserAllocated()));
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case PPB_ImageData_Shared::SIMPLE:
517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      backend_.reset(new ImageDataSimpleBackend);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
53a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      // No default: so that we get a compiler warning if any types are added.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochPPB_ImageData_Impl::PPB_ImageData_Impl(PP_Instance instance, ForTest)
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    : Resource(ppapi::OBJECT_IS_IMPL, instance),
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      format_(PP_IMAGEDATAFORMAT_BGRA_PREMUL),
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      width_(0),
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      height_(0) {
63a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  backend_.reset(new ImageDataPlatformBackend(false));
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
66a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochPPB_ImageData_Impl::~PPB_ImageData_Impl() {}
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PPB_ImageData_Impl::Init(PP_ImageDataFormat format,
69a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                              int width,
70a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                              int height,
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              bool init_to_zero) {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(brettw) this should be called only on the main thread!
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsImageDataFormatSupported(format))
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;  // Only support this one format for now.
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (width <= 0 || height <= 0)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (static_cast<int64>(width) * static_cast<int64>(height) >=
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      std::numeric_limits<int32>::max() / 4)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;  // Prevent overflow of signed 32-bit ints.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  format_ = format;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  width_ = width;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  height_ = height;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return backend_->Init(this, format, width, height, init_to_zero);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)PP_Resource PPB_ImageData_Impl::Create(PP_Instance instance,
897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                       PPB_ImageData_Shared::ImageDataType type,
907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                       PP_ImageDataFormat format,
917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                       const PP_Size& size,
927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                       PP_Bool init_to_zero) {
93a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  scoped_refptr<PPB_ImageData_Impl> data(
94a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      new PPB_ImageData_Impl(instance, type));
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!data->Init(format, size.width, size.height, !!init_to_zero))
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return data->GetReference();
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochPPB_ImageData_API* PPB_ImageData_Impl::AsPPB_ImageData_API() { return this; }
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochbool PPB_ImageData_Impl::IsMapped() const { return backend_->IsMapped(); }
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTransportDIB* PPB_ImageData_Impl::GetTransportDIB() const {
105558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return backend_->GetTransportDIB();
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Bool PPB_ImageData_Impl::Describe(PP_ImageDataDesc* desc) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  desc->format = format_;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  desc->size.width = width_;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  desc->size.height = height_;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  desc->stride = width_ * 4;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_TRUE;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid* PPB_ImageData_Impl::Map() { return backend_->Map(); }
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
118a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid PPB_ImageData_Impl::Unmap() { backend_->Unmap(); }
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t PPB_ImageData_Impl::GetSharedMemory(int* handle, uint32_t* byte_count) {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return backend_->GetSharedMemory(handle, byte_count);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)skia::PlatformCanvas* PPB_ImageData_Impl::GetPlatformCanvas() {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return backend_->GetPlatformCanvas();
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
128a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochSkCanvas* PPB_ImageData_Impl::GetCanvas() { return backend_->GetCanvas(); }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void PPB_ImageData_Impl::SetIsCandidateForReuse() {
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Nothing to do since we don't support image data re-use in-process.
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkBitmap* PPB_ImageData_Impl::GetMappedBitmap() const {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return backend_->GetMappedBitmap();
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// ImageDataPlatformBackend ----------------------------------------------------
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ImageDataPlatformBackend::ImageDataPlatformBackend(bool is_browser_allocated)
141a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    : width_(0), height_(0), is_browser_allocated_(is_browser_allocated) {}
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
143558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// On POSIX, we have to tell the browser to free the transport DIB.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageDataPlatformBackend::~ImageDataPlatformBackend() {
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (is_browser_allocated_) {
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_POSIX)
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (dib_) {
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      RenderThreadImpl::current()->Send(
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          new ViewHostMsg_FreeTransportDIB(dib_->id()));
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
151558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#endif
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ImageDataPlatformBackend::Init(PPB_ImageData_Impl* impl,
156558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                    PP_ImageDataFormat format,
157a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                    int width,
158a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                    int height,
159558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                    bool init_to_zero) {
160558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // TODO(brettw) use init_to_zero when we implement caching.
161558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  width_ = width;
162558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  height_ = height;
163558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  uint32 buffer_size = width_ * height_ * 4;
164558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
165558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Allocate the transport DIB and the PlatformCanvas pointing to it.
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  TransportDIB* dib = NULL;
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (is_browser_allocated_) {
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_POSIX)
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Allocate the image data by sending a message to the browser requesting a
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // TransportDIB (see also chrome/renderer/webplugin_delegate_proxy.cc,
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // method WebPluginDelegateProxy::CreateBitmap() for similar code). The
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // TransportDIB is cached in the browser, and is freed (in typical cases) by
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // the TransportDIB's destructor.
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    TransportDIB::Handle dib_handle;
175a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    IPC::Message* msg =
176a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        new ViewHostMsg_AllocTransportDIB(buffer_size, true, &dib_handle);
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!RenderThreadImpl::current()->Send(msg))
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return false;
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!TransportDIB::is_valid_handle(dib_handle))
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return false;
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    dib = TransportDIB::CreateWithHandle(dib_handle);
183558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#endif
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else {
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    static int next_dib_id = 0;
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    dib = TransportDIB::Create(buffer_size, next_dib_id++);
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!dib)
188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return false;
189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(dib);
191558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  dib_.reset(dib);
192558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return true;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ImageDataPlatformBackend::IsMapped() const {
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return !!mapped_canvas_.get();
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
199558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTransportDIB* ImageDataPlatformBackend::GetTransportDIB() const {
200558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return dib_.get();
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* ImageDataPlatformBackend::Map() {
204b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (!mapped_canvas_) {
205558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    mapped_canvas_.reset(dib_->GetPlatformCanvas(width_, height_));
206b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    if (!mapped_canvas_)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return NULL;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const SkBitmap& bitmap =
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      skia::GetTopDevice(*mapped_canvas_)->accessBitmap(true);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Our platform bitmaps are set to opaque by default, which we don't want.
2131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const_cast<SkBitmap&>(bitmap).setAlphaType(kPremul_SkAlphaType);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap.lockPixels();
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bitmap.getAddr32(0, 0);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ImageDataPlatformBackend::Unmap() {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is currently unimplemented, which is OK. The data will just always
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be around once it's mapped. Chrome's TransportDIB isn't currently
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // unmappable without freeing it, but this may be something we want to support
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in the future to save some memory.
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t ImageDataPlatformBackend::GetSharedMemory(int* handle,
227558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                                  uint32_t* byte_count) {
228558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  *byte_count = dib_->size();
229558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#if defined(OS_WIN)
230558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  *handle = reinterpret_cast<intptr_t>(dib_->handle());
231558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#else
232558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  *handle = static_cast<intptr_t>(dib_->handle().fd);
233558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#endif
234558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_OK;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)skia::PlatformCanvas* ImageDataPlatformBackend::GetPlatformCanvas() {
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return mapped_canvas_.get();
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
242a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochSkCanvas* ImageDataPlatformBackend::GetCanvas() { return mapped_canvas_.get(); }
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkBitmap* ImageDataPlatformBackend::GetMappedBitmap() const {
245b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (!mapped_canvas_)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return &skia::GetTopDevice(*mapped_canvas_)->accessBitmap(false);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// ImageDataSimpleBackend ------------------------------------------------------
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
252a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochImageDataSimpleBackend::ImageDataSimpleBackend() : map_count_(0) {}
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
254a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochImageDataSimpleBackend::~ImageDataSimpleBackend() {}
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool ImageDataSimpleBackend::Init(PPB_ImageData_Impl* impl,
2577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  PP_ImageDataFormat format,
258a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                  int width,
259a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                  int height,
2607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  bool init_to_zero) {
261116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  skia_bitmap_.setInfo(
262116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      SkImageInfo::MakeN32Premul(impl->width(), impl->height()));
263a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  shared_memory_.reset(
264a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      RenderThread::Get()
265a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          ->HostAllocateSharedMemoryBuffer(skia_bitmap_.getSize())
266a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          .release());
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return !!shared_memory_.get();
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
270a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochbool ImageDataSimpleBackend::IsMapped() const { return map_count_ > 0; }
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
272a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochTransportDIB* ImageDataSimpleBackend::GetTransportDIB() const { return NULL; }
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void* ImageDataSimpleBackend::Map() {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(shared_memory_.get());
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (map_count_++ == 0) {
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    shared_memory_->Map(skia_bitmap_.getSize());
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skia_bitmap_.setPixels(shared_memory_->memory());
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Our platform bitmaps are set to opaque by default, which we don't want.
2801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    skia_bitmap_.setAlphaType(kPremul_SkAlphaType);
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skia_canvas_.reset(new SkCanvas(skia_bitmap_));
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return skia_bitmap_.getAddr32(0, 0);
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return shared_memory_->memory();
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void ImageDataSimpleBackend::Unmap() {
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (--map_count_ == 0)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    shared_memory_->Unmap();
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)int32_t ImageDataSimpleBackend::GetSharedMemory(int* handle,
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                uint32_t* byte_count) {
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *byte_count = skia_bitmap_.getSize();
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *handle = shared_memory_->handle().fd;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_WIN)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *handle = reinterpret_cast<int>(shared_memory_->handle());
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#error "Platform not supported."
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_OK;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)skia::PlatformCanvas* ImageDataSimpleBackend::GetPlatformCanvas() {
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)SkCanvas* ImageDataSimpleBackend::GetCanvas() {
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsMapped())
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return skia_canvas_.get();
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)const SkBitmap* ImageDataSimpleBackend::GetMappedBitmap() const {
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsMapped())
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return &skia_bitmap_;
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch}  // namespace content
322