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_buffer_impl.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
11bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/renderer/pepper/common.h"
12558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/renderer/render_thread_impl.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/dev/ppb_buffer_dev.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)
18ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochusing ppapi::thunk::PPB_Buffer_API;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdochnamespace content {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_Buffer_Impl::PPB_Buffer_Impl(PP_Instance instance)
23ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    : Resource(ppapi::OBJECT_IS_IMPL, instance),
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size_(0),
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      map_count_(0) {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_Buffer_Impl::~PPB_Buffer_Impl() {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Resource PPB_Buffer_Impl::Create(PP_Instance instance, uint32_t size) {
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<PPB_Buffer_Impl> new_resource(CreateResource(instance, size));
34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (new_resource.get())
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return new_resource->GetReference();
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return 0;
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<PPB_Buffer_Impl> PPB_Buffer_Impl::CreateResource(
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PP_Instance instance,
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uint32_t size) {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<PPB_Buffer_Impl> buffer(new PPB_Buffer_Impl(instance));
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!buffer->Init(size))
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return scoped_refptr<PPB_Buffer_Impl>();
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return buffer;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_Buffer_Impl* PPB_Buffer_Impl::AsPPB_Buffer_Impl() {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return this;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_Buffer_API* PPB_Buffer_Impl::AsPPB_Buffer_API() {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return this;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PPB_Buffer_Impl::Init(uint32_t size) {
58d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (size == 0)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_ = size;
61558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  shared_memory_.reset(
62558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      RenderThread::Get()->HostAllocateSharedMemoryBuffer(size).release());
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return shared_memory_.get() != NULL;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Bool PPB_Buffer_Impl::Describe(uint32_t* size_in_bytes) {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *size_in_bytes = size_;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_TRUE;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Bool PPB_Buffer_Impl::IsMapped() {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_FromBool(!!shared_memory_->memory());
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* PPB_Buffer_Impl::Map() {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(size_);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(shared_memory_.get());
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (map_count_++ == 0)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    shared_memory_->Map(size_);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return shared_memory_->memory();
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PPB_Buffer_Impl::Unmap() {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (--map_count_ == 0)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    shared_memory_->Unmap();
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t PPB_Buffer_Impl::GetSharedMemory(int* shm_handle) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *shm_handle = shared_memory_->handle().fd;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_WIN)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *shm_handle = reinterpret_cast<int>(
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      shared_memory_->handle());
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#error "Platform not supported."
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_OK;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BufferAutoMapper::BufferAutoMapper(PPB_Buffer_API* api) : api_(api) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  needs_unmap_ = !PP_ToBool(api->IsMapped());
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_ = api->Map();
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  api->Describe(&size_);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BufferAutoMapper::~BufferAutoMapper() {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (needs_unmap_)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    api_->Unmap();
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch}  // namespace content
112