1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "content/renderer/pepper/ppb_buffer_impl.h" 6 7#include <algorithm> 8 9#include "base/logging.h" 10#include "base/memory/scoped_ptr.h" 11#include "content/renderer/pepper/common.h" 12#include "content/renderer/render_thread_impl.h" 13#include "ppapi/c/dev/ppb_buffer_dev.h" 14#include "ppapi/c/pp_errors.h" 15#include "ppapi/c/pp_instance.h" 16#include "ppapi/c/pp_resource.h" 17 18using ppapi::thunk::PPB_Buffer_API; 19 20namespace content { 21 22PPB_Buffer_Impl::PPB_Buffer_Impl(PP_Instance instance) 23 : Resource(ppapi::OBJECT_IS_IMPL, instance), size_(0), map_count_(0) {} 24 25PPB_Buffer_Impl::~PPB_Buffer_Impl() {} 26 27// static 28PP_Resource PPB_Buffer_Impl::Create(PP_Instance instance, uint32_t size) { 29 scoped_refptr<PPB_Buffer_Impl> new_resource(CreateResource(instance, size)); 30 if (new_resource.get()) 31 return new_resource->GetReference(); 32 return 0; 33} 34 35// static 36scoped_refptr<PPB_Buffer_Impl> PPB_Buffer_Impl::CreateResource( 37 PP_Instance instance, 38 uint32_t size) { 39 scoped_refptr<PPB_Buffer_Impl> buffer(new PPB_Buffer_Impl(instance)); 40 if (!buffer->Init(size)) 41 return scoped_refptr<PPB_Buffer_Impl>(); 42 return buffer; 43} 44 45PPB_Buffer_Impl* PPB_Buffer_Impl::AsPPB_Buffer_Impl() { return this; } 46 47PPB_Buffer_API* PPB_Buffer_Impl::AsPPB_Buffer_API() { return this; } 48 49bool PPB_Buffer_Impl::Init(uint32_t size) { 50 if (size == 0) 51 return false; 52 size_ = size; 53 shared_memory_.reset( 54 RenderThread::Get()->HostAllocateSharedMemoryBuffer(size).release()); 55 return shared_memory_.get() != NULL; 56} 57 58PP_Bool PPB_Buffer_Impl::Describe(uint32_t* size_in_bytes) { 59 *size_in_bytes = size_; 60 return PP_TRUE; 61} 62 63PP_Bool PPB_Buffer_Impl::IsMapped() { 64 return PP_FromBool(!!shared_memory_->memory()); 65} 66 67void* PPB_Buffer_Impl::Map() { 68 DCHECK(size_); 69 DCHECK(shared_memory_.get()); 70 if (map_count_++ == 0) 71 shared_memory_->Map(size_); 72 return shared_memory_->memory(); 73} 74 75void PPB_Buffer_Impl::Unmap() { 76 if (--map_count_ == 0) 77 shared_memory_->Unmap(); 78} 79 80int32_t PPB_Buffer_Impl::GetSharedMemory(int* shm_handle) { 81#if defined(OS_POSIX) 82 *shm_handle = shared_memory_->handle().fd; 83#elif defined(OS_WIN) 84 *shm_handle = reinterpret_cast<int>(shared_memory_->handle()); 85#else 86#error "Platform not supported." 87#endif 88 return PP_OK; 89} 90 91BufferAutoMapper::BufferAutoMapper(PPB_Buffer_API* api) : api_(api) { 92 needs_unmap_ = !PP_ToBool(api->IsMapped()); 93 data_ = api->Map(); 94 api->Describe(&size_); 95} 96 97BufferAutoMapper::~BufferAutoMapper() { 98 if (needs_unmap_) 99 api_->Unmap(); 100} 101 102} // namespace content 103