// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "content/renderer/pepper/ppb_buffer_impl.h" #include <algorithm> #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "content/renderer/pepper/common.h" #include "content/renderer/render_thread_impl.h" #include "ppapi/c/dev/ppb_buffer_dev.h" #include "ppapi/c/pp_errors.h" #include "ppapi/c/pp_instance.h" #include "ppapi/c/pp_resource.h" using ppapi::thunk::PPB_Buffer_API; namespace content { PPB_Buffer_Impl::PPB_Buffer_Impl(PP_Instance instance) : Resource(ppapi::OBJECT_IS_IMPL, instance), size_(0), map_count_(0) { } PPB_Buffer_Impl::~PPB_Buffer_Impl() { } // static PP_Resource PPB_Buffer_Impl::Create(PP_Instance instance, uint32_t size) { scoped_refptr<PPB_Buffer_Impl> new_resource(CreateResource(instance, size)); if (new_resource.get()) return new_resource->GetReference(); return 0; } // static scoped_refptr<PPB_Buffer_Impl> PPB_Buffer_Impl::CreateResource( PP_Instance instance, uint32_t size) { scoped_refptr<PPB_Buffer_Impl> buffer(new PPB_Buffer_Impl(instance)); if (!buffer->Init(size)) return scoped_refptr<PPB_Buffer_Impl>(); return buffer; } PPB_Buffer_Impl* PPB_Buffer_Impl::AsPPB_Buffer_Impl() { return this; } PPB_Buffer_API* PPB_Buffer_Impl::AsPPB_Buffer_API() { return this; } bool PPB_Buffer_Impl::Init(uint32_t size) { if (size == 0) return false; size_ = size; shared_memory_.reset( RenderThread::Get()->HostAllocateSharedMemoryBuffer(size).release()); return shared_memory_.get() != NULL; } PP_Bool PPB_Buffer_Impl::Describe(uint32_t* size_in_bytes) { *size_in_bytes = size_; return PP_TRUE; } PP_Bool PPB_Buffer_Impl::IsMapped() { return PP_FromBool(!!shared_memory_->memory()); } void* PPB_Buffer_Impl::Map() { DCHECK(size_); DCHECK(shared_memory_.get()); if (map_count_++ == 0) shared_memory_->Map(size_); return shared_memory_->memory(); } void PPB_Buffer_Impl::Unmap() { if (--map_count_ == 0) shared_memory_->Unmap(); } int32_t PPB_Buffer_Impl::GetSharedMemory(int* shm_handle) { #if defined(OS_POSIX) *shm_handle = shared_memory_->handle().fd; #elif defined(OS_WIN) *shm_handle = reinterpret_cast<int>( shared_memory_->handle()); #else #error "Platform not supported." #endif return PP_OK; } BufferAutoMapper::BufferAutoMapper(PPB_Buffer_API* api) : api_(api) { needs_unmap_ = !PP_ToBool(api->IsMapped()); data_ = api->Map(); api->Describe(&size_); } BufferAutoMapper::~BufferAutoMapper() { if (needs_unmap_) api_->Unmap(); } } // namespace content