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