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"
11558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/renderer/render_thread_impl.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/dev/ppb_buffer_dev.h"
13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ppapi/c/pp_bool.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)
23a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    : Resource(ppapi::OBJECT_IS_IMPL, instance), size_(0), map_count_(0) {}
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochPPB_Buffer_Impl::~PPB_Buffer_Impl() {}
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Resource PPB_Buffer_Impl::Create(PP_Instance instance, uint32_t size) {
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<PPB_Buffer_Impl> new_resource(CreateResource(instance, size));
30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (new_resource.get())
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return new_resource->GetReference();
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return 0;
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<PPB_Buffer_Impl> PPB_Buffer_Impl::CreateResource(
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PP_Instance instance,
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uint32_t size) {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<PPB_Buffer_Impl> buffer(new PPB_Buffer_Impl(instance));
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!buffer->Init(size))
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return scoped_refptr<PPB_Buffer_Impl>();
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return buffer;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochPPB_Buffer_Impl* PPB_Buffer_Impl::AsPPB_Buffer_Impl() { return this; }
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochPPB_Buffer_API* PPB_Buffer_Impl::AsPPB_Buffer_API() { return this; }
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PPB_Buffer_Impl::Init(uint32_t size) {
50d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (size == 0)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_ = size;
53558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  shared_memory_.reset(
54558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      RenderThread::Get()->HostAllocateSharedMemoryBuffer(size).release());
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return shared_memory_.get() != NULL;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Bool PPB_Buffer_Impl::Describe(uint32_t* size_in_bytes) {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *size_in_bytes = size_;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_TRUE;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Bool PPB_Buffer_Impl::IsMapped() {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_FromBool(!!shared_memory_->memory());
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* PPB_Buffer_Impl::Map() {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(size_);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(shared_memory_.get());
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (map_count_++ == 0)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    shared_memory_->Map(size_);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return shared_memory_->memory();
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PPB_Buffer_Impl::Unmap() {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (--map_count_ == 0)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    shared_memory_->Unmap();
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t PPB_Buffer_Impl::GetSharedMemory(int* shm_handle) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *shm_handle = shared_memory_->handle().fd;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_WIN)
84a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  *shm_handle = reinterpret_cast<int>(shared_memory_->handle());
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#error "Platform not supported."
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_OK;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BufferAutoMapper::BufferAutoMapper(PPB_Buffer_API* api) : api_(api) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  needs_unmap_ = !PP_ToBool(api->IsMapped());
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_ = api->Map();
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  api->Describe(&size_);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BufferAutoMapper::~BufferAutoMapper() {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (needs_unmap_)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    api_->Unmap();
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch}  // namespace content
103